0
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-11-03 06:35:19 +01:00

Merge f5f9637c1adc02eb2dd972b250f33b6a4209b95f into 98ff7d077376db1225f266095788c6bd9414288a

This commit is contained in:
cedstrom 2025-10-29 14:18:23 -07:00 committed by GitHub
commit 47f1c412c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 91 additions and 0 deletions

View File

@ -188,4 +188,6 @@ type ChangedFile struct {
ContentsURL string `json:"contents_url,omitempty"`
// The raw URL to download the file
RawURL string `json:"raw_url,omitempty"`
// The patch text for the file changes
Patch string `json:"patch,omitempty"`
}

View File

@ -812,6 +812,7 @@ func ToChangedFile(f *gitdiff.DiffFile, repo *repo_model.Repository, commit stri
HTMLURL: fmt.Sprint(repo.HTMLURL(), "/src/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
ContentsURL: fmt.Sprint(repo.APIURL(), "/contents/", util.PathEscapeSegments(f.GetDiffFileName()), "?ref=", commit),
RawURL: fmt.Sprint(repo.HTMLURL(), "/raw/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
Patch: gitdiff.RenderUnifiedDiff(f),
}
return file

View File

@ -1120,6 +1120,88 @@ func createDiffFile(line string) *DiffFile {
return curFile
}
func RenderUnifiedDiff(file *DiffFile) string {
var sb strings.Builder
oldPath := file.OldName
if oldPath == "" {
oldPath = file.Name
}
newPath := file.Name
// File header
fmt.Fprintf(&sb, "diff --git a/%s b/%s\n", oldPath, newPath)
fmt.Fprintf(&sb, "--- a/%s\n", oldPath)
fmt.Fprintf(&sb, "+++ b/%s\n", newPath)
if file.IsBin {
return ("Binary files differ\n\n")
}
for _, section := range file.Sections {
// Compute hunk header
leftStart, leftCount := hunkRange(section, true)
rightStart, rightCount := hunkRange(section, false)
fmt.Fprintf(&sb, "@@ -%d,%d +%d,%d @@\n", leftStart, leftCount, rightStart, rightCount)
for _, line := range section.Lines {
prefix := " "
switch line.Type {
case DiffLineAdd:
prefix = "+"
case DiffLineDel:
prefix = "-"
}
sb.WriteString(prefix + line.Content)
if !strings.HasSuffix(line.Content, "\n") {
sb.WriteString("\n")
}
}
}
sb.WriteString("\n")
return sb.String()
}
// hunkRange calculates the start and length for either old or new file in a section
func hunkRange(section *DiffSection, left bool) (start, count int) {
lines := section.Lines
if len(lines) == 0 {
return 0, 0
}
if left {
for _, l := range lines {
if l.LeftIdx > 0 {
start = l.LeftIdx
break
}
}
for _, l := range lines {
if l.LeftIdx > 0 {
count++
}
}
} else {
for _, l := range lines {
if l.RightIdx > 0 {
start = l.RightIdx
break
}
}
for _, l := range lines {
if l.RightIdx > 0 {
count++
}
}
}
if count == 0 {
count = 1
}
return start, count
}
func readFileName(rd *strings.Reader) (string, bool) {
ambiguity := false
var name string

View File

@ -22133,6 +22133,11 @@
"type": "string",
"x-go-name": "HTMLURL"
},
"patch": {
"description": "The patch text for the file changes",
"type": "string",
"x-go-name": "Patch"
},
"previous_filename": {
"description": "The previous filename if the file was renamed",
"type": "string",

View File

@ -84,6 +84,7 @@ func TestAPIViewPulls(t *testing.T) {
assert.Equal(t, 1, files[0].Changes)
assert.Equal(t, 0, files[0].Deletions)
assert.Equal(t, "added", files[0].Status)
assert.Equal(t, gitdiff.RenderUnifiedDiff(patch.Files[0]), files[0].Patch)
}
}))
}