Skip to content

Commit 78e257d

Browse files
committed
parser: Handle binary git patches
'git-format-patch' is able to generate binary patches. Fortunately, these are quite easy to spot since they're explicitly labelled as such. Add support for parsing these to the parser. Signed-off-by: Stephen Finucane <[email protected]> Closes: #463 (cherry picked from commit 6ba50aa)
1 parent f4c0503 commit 78e257d

File tree

5 files changed

+142
-2
lines changed

5 files changed

+142
-2
lines changed

patchwork/parser.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ def parse_patch(content):
852852
format, and splits it into the component comments and diff.
853853
854854
Args:
855-
patch: The patch to be split
855+
content: The mail to be split
856856
857857
Returns:
858858
A tuple containing the diff and comment. Either one or both of
@@ -874,6 +874,7 @@ def parse_patch(content):
874874
# 4: patch hunk header line (@@ line)
875875
# 5: patch hunk content
876876
# 6: patch meta header (rename from/rename to/new file/index)
877+
# 7: binary patch hunk
877878
#
878879
# valid transitions:
879880
# 0 -> 1 (diff, Index:)
@@ -882,10 +883,12 @@ def parse_patch(content):
882883
# 2 -> 3 (+++)
883884
# 3 -> 4 (@@ line)
884885
# 4 -> 5 (patch content)
885-
# 5 -> 1 (run out of lines from @@-specifed count)
886+
# 5 -> 1 (ran out of lines from @@-specified count)
886887
# 1 -> 6 (extended header lines)
887888
# 6 -> 2 (---)
889+
# 6 -> 7 (GIT binary patch)
888890
# 6 -> 1 (other text)
891+
# 7 -> 1 (diff)
889892
#
890893
# Suspected patch header is stored into buf, and appended to
891894
# patchbuf if we find a following hunk. Otherwise, append to
@@ -980,9 +983,20 @@ def fn(x):
980983
patchbuf += buf + line
981984
buf = ''
982985
state = 2
986+
elif line.startswith('GIT binary patch'):
987+
patchbuf += buf + line
988+
buf = ''
989+
state = 7
983990
else:
984991
buf += line
985992
state = 1
993+
elif state == 7:
994+
if line.startswith('diff'):
995+
buf += line
996+
state = 0
997+
else:
998+
patchbuf += buf + line
999+
buf = ''
9861000
else:
9871001
raise Exception("Unknown state %d! (line '%s')" % (state, line))
9881002

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
From 3029b9604cf2b2eaa5f38167f59246e2fa026eb5 Mon Sep 17 00:00:00 2001
2+
From: Stephen Finucane <[email protected]>
3+
Date: Wed, 11 May 2022 10:59:59 +0100
4+
Subject: [PATCH] Add a single pixel bitmap image
5+
6+
7+
Demonstrate how Git generates a patch for a binary file.
8+
9+
Signed-off-by: Stephen Finucane <[email protected]>
10+
---
11+
pixel.bmp | Bin 0 -> 142 bytes
12+
1 file changed, 0 insertions(+), 0 deletions(-)
13+
create mode 100644 pixel.bmp
14+
15+
diff --git pixel.bmp pixel.bmp
16+
new file mode 100644
17+
index 0000000000000000000000000000000000000000..9710347a13c4336e7dbaafa69af0e44a40c21172
18+
GIT binary patch
19+
literal 142
20+
zcmZ?r?PGv|E+AC{#Eft(0hV9^lFE7z3>E+r{}~t{2+VVG4=P5;5yxUeQzj#`nE?RC
21+
Ceh3`^
22+
23+
literal 0
24+
HcmV?d00001
25+
26+
--
27+
2.35.3
28+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
From 499d36d946a6f1f654eebad500742eb5c3057569 Mon Sep 17 00:00:00 2001
2+
From: Stephen Finucane <[email protected]>
3+
Date: Wed, 11 May 2022 10:33:58 +0100
4+
Subject: [PATCH] Add a single pixel bitmap image, minimal script
5+
6+
7+
Demonstrate how Git generates a patch for a binary file when mixed with
8+
other file types.
9+
10+
Signed-off-by: Stephen Finucane <[email protected]>
11+
---
12+
pixel.bmp | Bin 0 -> 142 bytes
13+
quit.sh | 3 +++
14+
2 files changed, 3 insertions(+)
15+
create mode 100644 pixel.bmp
16+
create mode 100644 quit.sh
17+
18+
diff --git pixel.bmp pixel.bmp
19+
new file mode 100644
20+
index 0000000000000000000000000000000000000000..9710347a13c4336e7dbaafa69af0e44a40c21172
21+
GIT binary patch
22+
literal 142
23+
zcmZ?r?PGv|E+AC{#Eft(0hV9^lFE7z3>E+r{}~t{2+VVG4=P5;5yxUeQzj#`nE?RC
24+
Ceh3`^
25+
26+
literal 0
27+
HcmV?d00001
28+
29+
diff --git quit.sh quit.sh
30+
new file mode 100644
31+
index 0000000..f5f929a
32+
--- /dev/null
33+
+++ quit.sh
34+
@@ -0,0 +1,3 @@
35+
+#/usr/bin/env bash
36+
+echo "Wuh wuh"
37+
+exit 1
38+
--
39+
2.35.3
40+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
From 434fe33a7ed28cc8cd0b344e55f0be2c74f1a58c Mon Sep 17 00:00:00 2001
2+
From: Stephen Finucane <[email protected]>
3+
Date: Wed, 11 May 2022 11:46:10 +0100
4+
Subject: [PATCH] Make changes to an existing binary file
5+
6+
7+
Signed-off-by: Stephen Finucane <[email protected]>
8+
---
9+
pixel.bmp | Bin 142 -> 0 bytes
10+
1 file changed, 0 insertions(+), 0 deletions(-)
11+
12+
diff --git pixel.bmp pixel.bmp
13+
index 9710347a13c4336e7dbaafa69af0e44a40c21172..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
14+
GIT binary patch
15+
literal 0
16+
HcmV?d00001
17+
18+
literal 142
19+
zcmZ?r?PGv|E+AC{#Eft(0hV9^lFE7z3>E+r{}~t{2+VVG4=P5;5yxUeQzj#`nE?RC
20+
Ceh3`^
21+
22+
--
23+
2.35.3
24+

patchwork/tests/test_parser.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,40 @@ def test_git_pull_trailing_space(self):
691691
'linux-davinci.git tags/davinci-for-v5.6/soc',
692692
pull_url)
693693

694+
def test_git_add_binary_file(self):
695+
diff, message = self._find_content('0025-git-add-binary-file.mbox')
696+
self.assertTrue(diff is not None)
697+
self.assertTrue(message is not None)
698+
self.assertTrue(
699+
diff.startswith('diff --git pixel.bmp pixel.bmp'), diff
700+
)
701+
self.assertIn('GIT binary patch\n', diff)
702+
self.assertIn('literal 142\n', diff)
703+
self.assertIn('literal 0\n', diff)
704+
705+
def test_git_add_mixed_binary_text_files(self):
706+
diff, message = self._find_content(
707+
'0026-git-add-mixed-binary-text-files.mbox'
708+
)
709+
self.assertTrue(diff is not None)
710+
self.assertTrue(message is not None)
711+
self.assertTrue(
712+
diff.startswith('diff --git pixel.bmp pixel.bmp'), diff
713+
)
714+
self.assertIn('GIT binary patch\n', diff)
715+
self.assertIn('diff --git quit.sh quit.sh\n', diff)
716+
717+
def test_git_modify_binary_file(self):
718+
diff, message = self._find_content('0027-git-modify-binary-file.mbox')
719+
self.assertTrue(diff is not None)
720+
self.assertTrue(message is not None)
721+
self.assertTrue(
722+
diff.startswith('diff --git pixel.bmp pixel.bmp'), diff
723+
)
724+
self.assertIn('GIT binary patch\n', diff)
725+
self.assertIn('literal 0\n', diff)
726+
self.assertIn('literal 142\n', diff)
727+
694728
def test_git_rename(self):
695729
diff, _ = self._find_content('0008-git-rename.mbox')
696730
self.assertTrue(diff is not None)

0 commit comments

Comments
 (0)