Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions modules/structs/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}
1 change: 1 addition & 0 deletions services/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
82 changes: 82 additions & 0 deletions services/gitdiff/gitdiff.go
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,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
Expand Down
5 changes: 5 additions & 0 deletions templates/swagger/v1_json.tmpl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tests/integration/api_pull_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,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)
}
}))
}
Expand Down