Skip to content
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

Add basic support for binary diffs #46

Merged
merged 3 commits into from May 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 70 additions & 0 deletions diff/diff_test.go
Expand Up @@ -388,6 +388,76 @@ func TestParseMultiFileDiffHeaders(t *testing.T) {
},
},
},
{
filename: "sample_binary_inline.diff",
wantDiffs: []*FileDiff{
{
OrigName: "a/logo-old.png",
OrigTime: nil,
NewName: "/dev/null",
NewTime: nil,
Extended: []string{
"diff --git a/logo-old.png b/logo-old.png",
"deleted file mode 100644",
"index d29d0e9757e0d9b854a8ed58f170bcb454cc1ae3..0000000000000000000000000000000000000000",
"GIT binary patch",
"literal 0",
"HcmV?d00001",
"",
"literal 0",
"HcmV?d00001",
"",
},
},
{
OrigName: "a/logo-old.png",
OrigTime: nil,
NewName: "b/logo-old.png",
NewTime: nil,
Extended: []string{
"diff --git a/logo-old.png b/logo-old.png",
"index ff82e793467f2050d731d75b4968d2e6b9c5d33b..d29d0e9757e0d9b854a8ed58f170bcb454cc1ae3 100644",
"GIT binary patch",
"literal 0",
"HcmV?d00001",
"",
"literal 0",
"HcmV?d00001",
"",
},
},
{
OrigName: "a/logo.png",
OrigTime: nil,
NewName: "b/logo-old.png",
NewTime: nil,
Extended: []string{
"diff --git a/logo.png b/logo-old.png",
"similarity index 100%",
"rename from logo.png",
"rename to logo-old.png",
},
},
{
OrigName: "/dev/null",
OrigTime: nil,
NewName: "b/logo.png",
NewTime: nil,
Extended: []string{
"diff --git a/logo.png b/logo.png",
"new file mode 100644",
"index 0000000000000000000000000000000000000000..ff82e793467f2050d731d75b4968d2e6b9c5d33b",
"GIT binary patch",
"literal 0",
"HcmV?d00001",
"",
"literal 0",
"HcmV?d00001",
"",
},
},
},
},
{
filename: "sample_multi_file_new_win.diff",
wantDiffs: []*FileDiff{
Expand Down
18 changes: 11 additions & 7 deletions diff/parse.go
Expand Up @@ -80,7 +80,7 @@ func (r *MultiFileDiffReader) ReadFile() (*FileDiff, error) {
// need to perform the check here.
hr := fr.HunksReader()
line, err := readLine(r.reader)
if err != nil {
if err != nil && err != io.EOF {
return fd, err
}
line = bytes.TrimSuffix(line, []byte{'\n'})
Expand Down Expand Up @@ -340,9 +340,13 @@ func (r *FileDiffReader) ReadExtendedHeaders() ([]string, error) {
// that follow. It updates fd fields from the parsed extended headers.
func handleEmpty(fd *FileDiff) (wasEmpty bool) {
var err error
lineCount := len(fd.Extended)
if lineCount > 0 && !strings.HasPrefix(fd.Extended[0], "diff --git ") {
return false
}
switch {
case (len(fd.Extended) == 3 || len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ")) &&
strings.HasPrefix(fd.Extended[1], "new file mode ") && strings.HasPrefix(fd.Extended[0], "diff --git "):
case (lineCount == 3 || lineCount == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ") || lineCount > 4 && strings.HasPrefix(fd.Extended[3], "GIT binary patch")) &&
strings.HasPrefix(fd.Extended[1], "new file mode "):

names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
fd.OrigName = "/dev/null"
Expand All @@ -351,8 +355,8 @@ func handleEmpty(fd *FileDiff) (wasEmpty bool) {
fd.NewName = names[1]
}
return true
case (len(fd.Extended) == 3 || len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ")) &&
strings.HasPrefix(fd.Extended[1], "deleted file mode ") && strings.HasPrefix(fd.Extended[0], "diff --git "):
case (lineCount == 3 || lineCount == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ") || lineCount > 4 && strings.HasPrefix(fd.Extended[3], "GIT binary patch")) &&
strings.HasPrefix(fd.Extended[1], "deleted file mode "):

names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
fd.OrigName, err = strconv.Unquote(names[0])
Expand All @@ -361,7 +365,7 @@ func handleEmpty(fd *FileDiff) (wasEmpty bool) {
}
fd.NewName = "/dev/null"
return true
case len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[2], "rename from ") && strings.HasPrefix(fd.Extended[3], "rename to ") && strings.HasPrefix(fd.Extended[0], "diff --git "):
case lineCount == 4 && strings.HasPrefix(fd.Extended[2], "rename from ") && strings.HasPrefix(fd.Extended[3], "rename to "):
names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
fd.OrigName, err = strconv.Unquote(names[0])
if err != nil {
Expand All @@ -372,7 +376,7 @@ func handleEmpty(fd *FileDiff) (wasEmpty bool) {
fd.NewName = names[1]
}
return true
case len(fd.Extended) == 3 && strings.HasPrefix(fd.Extended[2], "Binary files ") && strings.HasPrefix(fd.Extended[0], "diff --git "):
case lineCount == 3 && strings.HasPrefix(fd.Extended[2], "Binary files ") || lineCount > 3 && strings.HasPrefix(fd.Extended[2], "GIT binary patch"):
names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
fd.OrigName, err = strconv.Unquote(names[0])
if err != nil {
Expand Down
33 changes: 33 additions & 0 deletions diff/testdata/sample_binary_inline.diff
@@ -0,0 +1,33 @@
diff --git a/logo-old.png b/logo-old.png
deleted file mode 100644
index d29d0e9757e0d9b854a8ed58f170bcb454cc1ae3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 0
HcmV?d00001

diff --git a/logo-old.png b/logo-old.png
index ff82e793467f2050d731d75b4968d2e6b9c5d33b..d29d0e9757e0d9b854a8ed58f170bcb454cc1ae3 100644
GIT binary patch
literal 0
HcmV?d00001

literal 0
HcmV?d00001

diff --git a/logo.png b/logo-old.png
similarity index 100%
rename from logo.png
rename to logo-old.png
diff --git a/logo.png b/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..ff82e793467f2050d731d75b4968d2e6b9c5d33b
GIT binary patch
literal 0
HcmV?d00001

literal 0
HcmV?d00001