Skip to content

Fix ParsePatch function to work with quoted diff --git strings #6323

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 14, 2019
Merged
Show file tree
Hide file tree
Changes from 2 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
7 changes: 7 additions & 0 deletions models/git_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,13 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
beg := len(cmdDiffHead)
a := line[beg+2 : middle]
b := line[middle+3:]

if hasQuote {
// When /a and /b are surrounded by double quotes, we want to first
// make sure we keep everything the quotes and then strip out the leading /a /b
a = strings.Replace(line[beg:middle], "\"a/", "\"", -1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we just unquote then remove the first two runes. Using replace here is just complicating things.

Consider the, admittedly unusual case, of a file called: /a/a/a/a which is git mv and editted to /b/b/b/b. Your replace will just remove the entire names. (Yes you could change the replace to only replace one time but removing the first two characters is your aim.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yea that makes more sense/less complicated thx. Slipped my mind to change the string after unquoting. I've changed it to just remove the first 2 characters afterwards as you've suggested thx!

I agree entire integration tests are a good goal but I don't want to complicate or hold up what is otherwise just a couple line bug fix + adding a unit test here.

I'll look into understanding the integration testing more and perhaps help with something in a separate request if I can.

b = strings.Replace(line[middle+1:], "\"b/", "\"", -1)

var err error
a, err = strconv.Unquote(a)
if err != nil {
Expand Down Expand Up @@ -637,6 +643,7 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
}
}
}

return diff, nil
}

Expand Down
55 changes: 55 additions & 0 deletions models/git_diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"strings"
"testing"

"code.gitea.io/gitea/modules/setting"

dmp "github.com/sergi/go-diff/diffmatchpatch"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -99,6 +101,59 @@ func ExampleCutDiffAroundLine() {
println(result)
}

func TestParsePatch(t *testing.T) {
var diff = `diff --git "a/README.md" "b/README.md"
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
+ Build Status
- Latest Release
Docker Pulls
+ cut off
+ cut off`
result, err := ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
println(result)

var diff2 = `diff --git "a/A \\ B" "b/A \\ B"
--- "a/A \\ B"
+++ "b/A \\ B"
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
+ Build Status
- Latest Release
Docker Pulls
+ cut off
+ cut off`
result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
println(result)

var diff3 = `diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
+ Build Status
- Latest Release
Docker Pulls
+ cut off
+ cut off`
result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
println(result)
}

func setupDefaultDiff() *Diff {
return &Diff{
Files: []*DiffFile{
Expand Down