Simplify split diff view generation and remove JS dependency ()

Gitea has relied on some slow JS code to match up added and deleted lines on the
diff pages. This can cause a considerable slow down on large diff pages.

This PR makes a small change meaning that the matching up can occur much more simply.

Partial fix 

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath 2021-08-29 15:28:04 +01:00 committed by GitHub
parent d24eb6e6ce
commit f5b0e2c9d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 109 additions and 75 deletions
modules/repofiles
services/gitdiff
templates/repo/diff

View file

@ -83,6 +83,7 @@ func TestGetDiffPreview(t *testing.T) {
{ {
LeftIdx: 3, LeftIdx: 3,
RightIdx: 0, RightIdx: 0,
Match: 4,
Type: 3, Type: 3,
Content: "-Description for repo1", Content: "-Description for repo1",
Comments: nil, Comments: nil,
@ -90,6 +91,7 @@ func TestGetDiffPreview(t *testing.T) {
{ {
LeftIdx: 0, LeftIdx: 0,
RightIdx: 3, RightIdx: 3,
Match: 3,
Type: 2, Type: 2,
Content: "+Description for repo1", Content: "+Description for repo1",
Comments: nil, Comments: nil,
@ -97,6 +99,7 @@ func TestGetDiffPreview(t *testing.T) {
{ {
LeftIdx: 0, LeftIdx: 0,
RightIdx: 4, RightIdx: 4,
Match: -1,
Type: 2, Type: 2,
Content: "+this is a new line", Content: "+this is a new line",
Comments: nil, Comments: nil,

View file

@ -75,6 +75,7 @@ const (
type DiffLine struct { type DiffLine struct {
LeftIdx int LeftIdx int
RightIdx int RightIdx int
Match int
Type DiffLineType Type DiffLineType
Content string Content string
Comments []*models.Comment Comments []*models.Comment
@ -943,6 +944,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
curFileLFSPrefix bool curFileLFSPrefix bool
) )
lastLeftIdx := -1
leftLine, rightLine := 1, 1 leftLine, rightLine := 1, 1
for { for {
@ -1027,13 +1029,21 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
curFile.IsIncomplete = true curFile.IsIncomplete = true
continue continue
} }
diffLine := &DiffLine{Type: DiffLineAdd, RightIdx: rightLine} diffLine := &DiffLine{Type: DiffLineAdd, RightIdx: rightLine, Match: -1}
rightLine++ rightLine++
if curSection == nil { if curSection == nil {
// Create a new section to represent this hunk // Create a new section to represent this hunk
curSection = &DiffSection{} curSection = &DiffSection{}
curFile.Sections = append(curFile.Sections, curSection) curFile.Sections = append(curFile.Sections, curSection)
} }
if lastLeftIdx > -1 {
diffLine.Match = lastLeftIdx
curSection.Lines[lastLeftIdx].Match = len(curSection.Lines)
lastLeftIdx++
if lastLeftIdx >= len(curSection.Lines) || curSection.Lines[lastLeftIdx].Type != DiffLineDel {
lastLeftIdx = -1
}
}
curSection.Lines = append(curSection.Lines, diffLine) curSection.Lines = append(curSection.Lines, diffLine)
case '-': case '-':
curFileLinesCount++ curFileLinesCount++
@ -1042,7 +1052,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
curFile.IsIncomplete = true curFile.IsIncomplete = true
continue continue
} }
diffLine := &DiffLine{Type: DiffLineDel, LeftIdx: leftLine} diffLine := &DiffLine{Type: DiffLineDel, LeftIdx: leftLine, Match: -1}
if leftLine > 0 { if leftLine > 0 {
leftLine++ leftLine++
} }
@ -1051,6 +1061,9 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
curSection = &DiffSection{} curSection = &DiffSection{}
curFile.Sections = append(curFile.Sections, curSection) curFile.Sections = append(curFile.Sections, curSection)
} }
if len(curSection.Lines) == 0 || curSection.Lines[len(curSection.Lines)-1].Type != DiffLineDel {
lastLeftIdx = len(curSection.Lines)
}
curSection.Lines = append(curSection.Lines, diffLine) curSection.Lines = append(curSection.Lines, diffLine)
case ' ': case ' ':
curFileLinesCount++ curFileLinesCount++
@ -1061,6 +1074,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
diffLine := &DiffLine{Type: DiffLinePlain, LeftIdx: leftLine, RightIdx: rightLine} diffLine := &DiffLine{Type: DiffLinePlain, LeftIdx: leftLine, RightIdx: rightLine}
leftLine++ leftLine++
rightLine++ rightLine++
lastLeftIdx = -1
if curSection == nil { if curSection == nil {
// Create a new section to represent this hunk // Create a new section to represent this hunk
curSection = &DiffSection{} curSection = &DiffSection{}

View file

@ -154,33 +154,5 @@
{{end}} {{end}}
{{template "repo/issue/view_content/reference_issue_dialog" .}} {{template "repo/issue/view_content/reference_issue_dialog" .}}
{{if .IsSplitStyle}}
<script>
document.addEventListener('DOMContentLoaded', () => {
$('tr.add-code').each(function() {
let prev = $(this).prev();
if (prev.is('.del-code') && prev.children().eq(5).text().trim() === '') {
while (prev.prev().is('.del-code') && prev.prev().children().eq(5).text().trim() === '') {
prev = prev.prev();
}
prev.children().eq(3).attr('data-line-num', $(this).children().eq(3).attr('data-line-num'));
prev.children().eq(3).html($(this).children().eq(3).html());
prev.children().eq(4).html($(this).children().eq(4).html());
prev.children().eq(5).html($(this).children().eq(5).html());
prev.children().eq(0).addClass('del-code');
prev.children().eq(1).addClass('del-code');
prev.children().eq(2).addClass('del-code');
prev.children().eq(3).addClass('add-code');
prev.children().eq(4).addClass('add-code');
prev.children().eq(5).addClass('add-code');
$(this).remove();
}
});
});
</script>
{{end}}
</div> </div>
{{end}} {{end}}

View file

@ -1,6 +1,8 @@
{{$file := .file}} {{$file := .file}}
{{range $j, $section := $file.Sections}} {{range $j, $section := $file.Sections}}
{{range $k, $line := $section.Lines}} {{range $k, $line := $section.Lines}}
{{$hasmatch := ne $line.Match -1}}
{{if or (ne .GetType 2) (not $hasmatch)}}
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}" data-line-type="{{DiffLineTypeToStr .GetType}}"> <tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}" data-line-type="{{DiffLineTypeToStr .GetType}}">
{{if eq .GetType 4}} {{if eq .GetType 4}}
<td class="lines-num lines-num-old"> <td class="lines-num lines-num-old">
@ -21,6 +23,14 @@
{{end}} {{end}}
</td> </td>
<td colspan="5" class="lines-code lines-code-old "><code class="code-inner">{{$section.GetComputedInlineDiffFor $line}}</span></td> <td colspan="5" class="lines-code lines-code-old "><code class="code-inner">{{$section.GetComputedInlineDiffFor $line}}</span></td>
{{else if and (eq .GetType 3) $hasmatch}}{{/* DEL */}}
{{$match := index $section.Lines $line.Match}}
<td class="lines-num lines-num-old del-code" data-line-num="{{$line.LeftIdx}}"><span rel="diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}"></span></td>
<td class="lines-type-marker lines-type-marker-old del-code"><span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
<td class="lines-code lines-code-old halfwidth del-code">{{if and $.root.SignedUserID $.root.PageIsPullFiles}}<a class="ui primary button add-code-comment add-code-comment-left{{if (not $line.CanComment)}} invisible{{end}}" data-path="{{$file.Name}}" data-side="left" data-idx="{{$line.LeftIdx}}" data-new-comment-url="{{$.root.Issue.HTMLURL}}/files/reviews/new_comment">{{svg "octicon-plus"}}</a>{{end}}<code class="code-inner">{{if $line.LeftIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></td>
<td class="lines-num lines-num-new add-code" data-line-num="{{if $match.RightIdx}}{{$match.RightIdx}}{{end}}"><span rel="{{if $match.RightIdx}}diff-{{Sha1 $file.Name}}R{{$match.RightIdx}}{{end}}"></span></td>
<td class="lines-type-marker lines-type-marker-new add-code">{{if $match.RightIdx}}<span class="mono" data-type-marker="{{$match.GetLineTypeMarker}}"></span>{{end}}</td>
<td class="lines-code lines-code-new halfwidth add-code">{{if and $.root.SignedUserID $.root.PageIsPullFiles}}<a class="ui primary button add-code-comment add-code-comment-right{{if (not $match.CanComment)}} invisible{{end}}" data-path="{{$file.Name}}" data-side="right" data-idx="{{$match.RightIdx}}" data-new-comment-url="{{$.root.Issue.HTMLURL}}/files/reviews/new_comment">{{svg "octicon-plus"}}</a>{{end}}<code class="code-inner">{{if $match.RightIdx}}{{$section.GetComputedInlineDiffFor $match}}{{end}}</code></td>
{{else}} {{else}}
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}"></span></td> <td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}"></span></td>
<td class="lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td> <td class="lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td>
@ -30,14 +40,48 @@
<td class="lines-code lines-code-new halfwidth">{{if and $.root.SignedUserID $.root.PageIsPullFiles (not (eq .GetType 3))}}<a class="ui primary button add-code-comment add-code-comment-right{{if (not $line.CanComment)}} invisible{{end}}" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}" data-new-comment-url="{{$.root.Issue.HTMLURL}}/files/reviews/new_comment">{{svg "octicon-plus"}}</a>{{end}}<code class="code-inner">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></td> <td class="lines-code lines-code-new halfwidth">{{if and $.root.SignedUserID $.root.PageIsPullFiles (not (eq .GetType 3))}}<a class="ui primary button add-code-comment add-code-comment-right{{if (not $line.CanComment)}} invisible{{end}}" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}" data-new-comment-url="{{$.root.Issue.HTMLURL}}/files/reviews/new_comment">{{svg "octicon-plus"}}</a>{{end}}<code class="code-inner">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></td>
{{end}} {{end}}
</tr> </tr>
{{if gt (len $line.Comments) 0}} {{if and (eq .GetType 3) $hasmatch}}
{{$match := index $section.Lines $line.Match}}
{{if or (gt (len $line.Comments) 0) (gt (len $match.Comments) 0)}}
<tr class="add-comment" data-line-type="{{DiffLineTypeToStr .GetType}}"> <tr class="add-comment" data-line-type="{{DiffLineTypeToStr .GetType}}">
<td class="lines-num"></td> <td class="lines-num"></td>
<td class="lines-type-marker"></td> <td class="lines-type-marker"></td>
<td class="add-comment-left"> <td class="add-comment-left">
{{if gt (len $line.Comments) 0}}
{{if eq $line.GetCommentSide "previous"}} {{if eq $line.GetCommentSide "previous"}}
{{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}} {{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}}
{{end}} {{end}}
{{end}}
{{if gt (len $match.Comments) 0}}
{{if eq $match.GetCommentSide "previous"}}
{{template "repo/diff/conversation" mergeinto $.root "comments" $match.Comments}}
{{end}}
{{end}}
</td>
<td class="lines-num"></td>
<td class="lines-type-marker"></td>
<td class="add-comment-right">
{{if eq $line.GetCommentSide "proposed"}}
{{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}}
{{end}}
{{if gt (len $match.Comments) 0}}
{{if eq $match.GetCommentSide "proposed"}}
{{template "repo/diff/conversation" mergeinto $.root "comments" $match.Comments}}
{{end}}
{{end}}
</td>
</tr>
{{end}}
{{else if gt (len $line.Comments) 0}}
<tr class="add-comment" data-line-type="{{DiffLineTypeToStr .GetType}}">
<td class="lines-num"></td>
<td class="lines-type-marker"></td>
<td class="add-comment-left">
{{if gt (len $line.Comments) 0}}
{{if eq $line.GetCommentSide "previous"}}
{{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}}
{{end}}
{{end}}
</td> </td>
<td class="lines-num"></td> <td class="lines-num"></td>
<td class="lines-type-marker"></td> <td class="lines-type-marker"></td>
@ -49,4 +93,5 @@
</tr> </tr>
{{end}} {{end}}
{{end}} {{end}}
{{end}}
{{end}} {{end}}