Skip to content

Commit f935979

Browse files
authored
Add basic support for binary diffs (#46)
1 parent 8c3ae63 commit f935979

File tree

3 files changed

+114
-7
lines changed

3 files changed

+114
-7
lines changed

diff/diff_test.go

+70
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,76 @@ func TestParseMultiFileDiffHeaders(t *testing.T) {
388388
},
389389
},
390390
},
391+
{
392+
filename: "sample_binary_inline.diff",
393+
wantDiffs: []*FileDiff{
394+
{
395+
OrigName: "a/logo-old.png",
396+
OrigTime: nil,
397+
NewName: "/dev/null",
398+
NewTime: nil,
399+
Extended: []string{
400+
"diff --git a/logo-old.png b/logo-old.png",
401+
"deleted file mode 100644",
402+
"index d29d0e9757e0d9b854a8ed58f170bcb454cc1ae3..0000000000000000000000000000000000000000",
403+
"GIT binary patch",
404+
"literal 0",
405+
"HcmV?d00001",
406+
"",
407+
"literal 0",
408+
"HcmV?d00001",
409+
"",
410+
},
411+
},
412+
{
413+
OrigName: "a/logo-old.png",
414+
OrigTime: nil,
415+
NewName: "b/logo-old.png",
416+
NewTime: nil,
417+
Extended: []string{
418+
"diff --git a/logo-old.png b/logo-old.png",
419+
"index ff82e793467f2050d731d75b4968d2e6b9c5d33b..d29d0e9757e0d9b854a8ed58f170bcb454cc1ae3 100644",
420+
"GIT binary patch",
421+
"literal 0",
422+
"HcmV?d00001",
423+
"",
424+
"literal 0",
425+
"HcmV?d00001",
426+
"",
427+
},
428+
},
429+
{
430+
OrigName: "a/logo.png",
431+
OrigTime: nil,
432+
NewName: "b/logo-old.png",
433+
NewTime: nil,
434+
Extended: []string{
435+
"diff --git a/logo.png b/logo-old.png",
436+
"similarity index 100%",
437+
"rename from logo.png",
438+
"rename to logo-old.png",
439+
},
440+
},
441+
{
442+
OrigName: "/dev/null",
443+
OrigTime: nil,
444+
NewName: "b/logo.png",
445+
NewTime: nil,
446+
Extended: []string{
447+
"diff --git a/logo.png b/logo.png",
448+
"new file mode 100644",
449+
"index 0000000000000000000000000000000000000000..ff82e793467f2050d731d75b4968d2e6b9c5d33b",
450+
"GIT binary patch",
451+
"literal 0",
452+
"HcmV?d00001",
453+
"",
454+
"literal 0",
455+
"HcmV?d00001",
456+
"",
457+
},
458+
},
459+
},
460+
},
391461
{
392462
filename: "sample_multi_file_new_win.diff",
393463
wantDiffs: []*FileDiff{

diff/parse.go

+11-7
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func (r *MultiFileDiffReader) ReadFile() (*FileDiff, error) {
8080
// need to perform the check here.
8181
hr := fr.HunksReader()
8282
line, err := readLine(r.reader)
83-
if err != nil {
83+
if err != nil && err != io.EOF {
8484
return fd, err
8585
}
8686
line = bytes.TrimSuffix(line, []byte{'\n'})
@@ -340,9 +340,13 @@ func (r *FileDiffReader) ReadExtendedHeaders() ([]string, error) {
340340
// that follow. It updates fd fields from the parsed extended headers.
341341
func handleEmpty(fd *FileDiff) (wasEmpty bool) {
342342
var err error
343+
lineCount := len(fd.Extended)
344+
if lineCount > 0 && !strings.HasPrefix(fd.Extended[0], "diff --git ") {
345+
return false
346+
}
343347
switch {
344-
case (len(fd.Extended) == 3 || len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ")) &&
345-
strings.HasPrefix(fd.Extended[1], "new file mode ") && strings.HasPrefix(fd.Extended[0], "diff --git "):
348+
case (lineCount == 3 || lineCount == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ") || lineCount > 4 && strings.HasPrefix(fd.Extended[3], "GIT binary patch")) &&
349+
strings.HasPrefix(fd.Extended[1], "new file mode "):
346350

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

357361
names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
358362
fd.OrigName, err = strconv.Unquote(names[0])
@@ -361,7 +365,7 @@ func handleEmpty(fd *FileDiff) (wasEmpty bool) {
361365
}
362366
fd.NewName = "/dev/null"
363367
return true
364-
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 "):
368+
case lineCount == 4 && strings.HasPrefix(fd.Extended[2], "rename from ") && strings.HasPrefix(fd.Extended[3], "rename to "):
365369
names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
366370
fd.OrigName, err = strconv.Unquote(names[0])
367371
if err != nil {
@@ -372,7 +376,7 @@ func handleEmpty(fd *FileDiff) (wasEmpty bool) {
372376
fd.NewName = names[1]
373377
}
374378
return true
375-
case len(fd.Extended) == 3 && strings.HasPrefix(fd.Extended[2], "Binary files ") && strings.HasPrefix(fd.Extended[0], "diff --git "):
379+
case lineCount == 3 && strings.HasPrefix(fd.Extended[2], "Binary files ") || lineCount > 3 && strings.HasPrefix(fd.Extended[2], "GIT binary patch"):
376380
names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2)
377381
fd.OrigName, err = strconv.Unquote(names[0])
378382
if err != nil {
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
diff --git a/logo-old.png b/logo-old.png
2+
deleted file mode 100644
3+
index d29d0e9757e0d9b854a8ed58f170bcb454cc1ae3..0000000000000000000000000000000000000000
4+
GIT binary patch
5+
literal 0
6+
HcmV?d00001
7+
8+
literal 0
9+
HcmV?d00001
10+
11+
diff --git a/logo-old.png b/logo-old.png
12+
index ff82e793467f2050d731d75b4968d2e6b9c5d33b..d29d0e9757e0d9b854a8ed58f170bcb454cc1ae3 100644
13+
GIT binary patch
14+
literal 0
15+
HcmV?d00001
16+
17+
literal 0
18+
HcmV?d00001
19+
20+
diff --git a/logo.png b/logo-old.png
21+
similarity index 100%
22+
rename from logo.png
23+
rename to logo-old.png
24+
diff --git a/logo.png b/logo.png
25+
new file mode 100644
26+
index 0000000000000000000000000000000000000000..ff82e793467f2050d731d75b4968d2e6b9c5d33b
27+
GIT binary patch
28+
literal 0
29+
HcmV?d00001
30+
31+
literal 0
32+
HcmV?d00001
33+

0 commit comments

Comments
 (0)