mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-03 11:05:13 +02:00
chore: fix git diff render (#38746)
Fix a regression from #38517 (the tail section index is not correctly assigned). And add a test to cover GetDiffForRender.
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/modules/git/gitcmd"
|
||||
"gitea.dev/modules/util"
|
||||
)
|
||||
|
||||
type FastImportFile struct {
|
||||
@@ -27,11 +28,13 @@ type FastImportCommit struct {
|
||||
func ForceFastImport(ctx context.Context, repo RepositoryFacade, commits []FastImportCommit) error {
|
||||
var buf bytes.Buffer
|
||||
for i, c := range commits {
|
||||
msg := util.IfZero(c.Message, fmt.Sprintf("commit %d", i+1))
|
||||
_, _ = fmt.Fprintf(&buf, "reset %s\n", c.Ref)
|
||||
_, _ = fmt.Fprintf(&buf, "commit %s\nmark :%d\ncommitter Gitea <gitea@example.com> 1500000000 +0000\n", c.Ref, i+1)
|
||||
_, _ = fmt.Fprintf(&buf, "data %d\n%s\n", len(c.Message), c.Message)
|
||||
_, _ = fmt.Fprintf(&buf, "data %d\n%s\n", len(msg), msg)
|
||||
for _, f := range c.Files {
|
||||
_, _ = fmt.Fprintf(&buf, "M %s inline %s\ndata %d\n%s\n", f.Mode.String(), f.Path, len(f.Content), f.Content)
|
||||
mode := util.IfZero(f.Mode, EntryModeBlob)
|
||||
_, _ = fmt.Fprintf(&buf, "M %s inline %s\ndata %d\n%s\n", mode.String(), f.Path, len(f.Content), f.Content)
|
||||
}
|
||||
}
|
||||
buf.WriteString("done\n")
|
||||
|
||||
@@ -503,16 +503,15 @@ func (diffFile *DiffFile) prepareDiffRenderDetail(ctx context.Context, gitRepo *
|
||||
// * for "bin" type: need the pre-fetched buffer to detect content type (e.g.: help to render image diff)
|
||||
// * for "text" type: need to read up to "highlight limit size" to do full-file-highlighting
|
||||
contentLimit := util.Iif(diffFile.IsBin, typesniffer.SniffContentSize, MaxFullFileHighlightSizeLimit)
|
||||
var leftLineCount, rightLineCount int
|
||||
var leftBlobType, rightBlobType typesniffer.SniffedType
|
||||
if (diffFile.Type == DiffFileDel || diffFile.Type == DiffFileChange) && leftCommit != nil {
|
||||
c := getCommitFileBlobAndLimitedContent(ctx, gitRepo, leftCommit, diffFile.OldName, contentLimit)
|
||||
diffFile.LeftBlob, diffFile.LeftBlobSize, leftLineCount, ret.leftContent = c.gitBlob, c.blobSize, c.lineCount, c.limitedContent
|
||||
diffFile.LeftBlob, diffFile.LeftBlobSize, ret.leftLineCount, ret.leftContent = c.gitBlob, c.blobSize, c.lineCount, c.limitedContent
|
||||
leftBlobType = typesniffer.DetectContentType(ret.leftContent.buf.Bytes())
|
||||
}
|
||||
if (diffFile.Type == DiffFileAdd || diffFile.Type == DiffFileChange) && rightCommit != nil {
|
||||
c := getCommitFileBlobAndLimitedContent(ctx, gitRepo, rightCommit, diffFile.OldName, contentLimit)
|
||||
diffFile.RightBlob, diffFile.RightBlobSize, rightLineCount, ret.rightContent = c.gitBlob, c.blobSize, c.lineCount, c.limitedContent
|
||||
diffFile.RightBlob, diffFile.RightBlobSize, ret.rightLineCount, ret.rightContent = c.gitBlob, c.blobSize, c.lineCount, c.limitedContent
|
||||
rightBlobType = typesniffer.DetectContentType(ret.rightContent.buf.Bytes())
|
||||
}
|
||||
|
||||
@@ -534,7 +533,7 @@ func (diffFile *DiffFile) prepareDiffRenderDetail(ctx context.Context, gitRepo *
|
||||
// check whether the text file diff needs a tail section
|
||||
lastSection := diffFile.Sections[len(diffFile.Sections)-1]
|
||||
lastLine := lastSection.Lines[len(lastSection.Lines)-1]
|
||||
if leftLineCount <= lastLine.LeftIdx || rightLineCount <= lastLine.RightIdx {
|
||||
if ret.leftLineCount <= lastLine.LeftIdx || ret.rightLineCount <= lastLine.RightIdx {
|
||||
return ret
|
||||
}
|
||||
ret.needTailSection = true
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package gitdiff
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modules/git"
|
||||
"gitea.dev/modules/setting"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetDiffForRender(t *testing.T) {
|
||||
repoDir := filepath.Join(t.TempDir(), "temp-repo")
|
||||
require.NoError(t, git.InitRepositoryLocal(t.Context(), repoDir, false, git.Sha1ObjectFormat.Name()))
|
||||
|
||||
contentLeft := strings.Repeat("a\n", 20) +
|
||||
"mark1\n" +
|
||||
strings.Repeat("b\n", 10) +
|
||||
"mark2\n" +
|
||||
strings.Repeat("c\n", 40) +
|
||||
"mark3\n" +
|
||||
strings.Repeat("a\n", 30)
|
||||
contentRight := strings.Repeat("a\n", 20-1) +
|
||||
"mark1-x\n" +
|
||||
strings.Repeat("b\n", 10+3) +
|
||||
"mark2-x\n" +
|
||||
strings.Repeat("c\n", 40-5) +
|
||||
"mark3-x\n" +
|
||||
strings.Repeat("a\n", 30)
|
||||
|
||||
gitRepo, err := git.OpenRepositoryLocal(t.Context(), repoDir)
|
||||
require.NoError(t, err)
|
||||
defer gitRepo.Close()
|
||||
|
||||
require.NoError(t, git.ForceFastImport(t.Context(), gitRepo, []git.FastImportCommit{
|
||||
{Ref: "refs/heads/b1", Files: []git.FastImportFile{{Path: "foo.txt", Content: contentLeft}}},
|
||||
{Ref: "refs/heads/b2", Files: []git.FastImportFile{{Path: "foo.txt", Content: contentRight}}},
|
||||
}))
|
||||
|
||||
beforeCommit, err := gitRepo.GetBranchCommit(t.Context(), "b1")
|
||||
require.NoError(t, err)
|
||||
afterCommit, err := gitRepo.GetBranchCommit(t.Context(), "b2")
|
||||
require.NoError(t, err)
|
||||
|
||||
diff, err := GetDiffForRender(t.Context(), "/any/repo-link", gitRepo, &DiffOptions{
|
||||
BeforeCommitID: beforeCommit.ID.String(),
|
||||
AfterCommitID: afterCommit.ID.String(),
|
||||
MaxLines: setting.Git.MaxGitDiffLines,
|
||||
MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
|
||||
MaxFiles: setting.Git.MaxGitDiffFiles,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, diff.Files, 1)
|
||||
|
||||
type section struct {
|
||||
ExpandDirection string
|
||||
|
||||
LastLeftIdx int
|
||||
LastRightIdx int
|
||||
LeftIdx int
|
||||
RightIdx int
|
||||
LeftHunkSize int
|
||||
RightHunkSize int
|
||||
}
|
||||
expectedSections := []section{
|
||||
{
|
||||
ExpandDirection: "up",
|
||||
LeftIdx: 17,
|
||||
RightIdx: 17,
|
||||
LeftHunkSize: 8,
|
||||
RightHunkSize: 7,
|
||||
},
|
||||
{
|
||||
ExpandDirection: "single",
|
||||
LastLeftIdx: 24,
|
||||
LastRightIdx: 23,
|
||||
LeftIdx: 29,
|
||||
RightIdx: 28,
|
||||
LeftHunkSize: 7,
|
||||
RightHunkSize: 10,
|
||||
},
|
||||
{
|
||||
ExpandDirection: "updown",
|
||||
LastLeftIdx: 35,
|
||||
LastRightIdx: 37,
|
||||
LeftIdx: 65,
|
||||
RightIdx: 67,
|
||||
LeftHunkSize: 12,
|
||||
RightHunkSize: 7,
|
||||
},
|
||||
{
|
||||
ExpandDirection: "down",
|
||||
LastLeftIdx: 76,
|
||||
LastRightIdx: 73,
|
||||
LeftIdx: 104,
|
||||
RightIdx: 101,
|
||||
},
|
||||
}
|
||||
for idx, exp := range expectedSections {
|
||||
secLine := diff.Files[0].Sections[idx].Lines[0] // line 0 should be the "section info"
|
||||
actual := section{
|
||||
ExpandDirection: secLine.GetExpandDirection(),
|
||||
LastLeftIdx: secLine.SectionInfo.LastLeftIdx,
|
||||
LastRightIdx: secLine.SectionInfo.LastRightIdx,
|
||||
LeftIdx: secLine.SectionInfo.LeftIdx,
|
||||
RightIdx: secLine.SectionInfo.RightIdx,
|
||||
LeftHunkSize: secLine.SectionInfo.LeftHunkSize,
|
||||
RightHunkSize: secLine.SectionInfo.RightHunkSize,
|
||||
}
|
||||
assert.Equal(t, exp, actual, "idx=%d", idx)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user