Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion patch_ng.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,9 @@ def _detect_type(self, p):
break
if p.header[idx].startswith(b'diff --git a/'):
if (idx+1 < len(p.header)
and re.match(b'(?:index \\w{7}..\\w{7} \\d{6}|new file mode \\d*)', p.header[idx+1])):
and re.match(
b'(?:index \\w{4,40}\\.\\.\\w{4,40}(?: \\d{6})?|new file mode \\d+|deleted file mode \\d+)',
p.header[idx+1])):
if DVCS:
return GIT

Expand Down
20 changes: 20 additions & 0 deletions tests/patchformat/create.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
From 8cacee878aff9a79603c87366d3eeefa68d80cf3 Mon Sep 17 00:00:00 2001
From: John Doe <john.doe@email.com>
Date: Wed, 1 Oct 2025 10:59:19 +0200
Subject: [PATCH] Add quotes.txt

Signed-off-by: John Doe <john.doe@email.com>
---
quotes.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 quotes.txt

diff --git a/quotes.txt b/quotes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..edcfcc5846847fffa4986b8437f1d7a3bd8aa8cf
--- /dev/null
+++ b/quotes.txt
@@ -0,0 +1 @@
+habita fides ipsam plerumque obligat fidem.
--
2.51.0
20 changes: 20 additions & 0 deletions tests/patchformat/remove.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
From 22751ffae72c0b955b55e68ec0e25a80e434e890 Mon Sep 17 00:00:00 2001
From: John Doe <john.doe@email.com>
Date: Wed, 1 Oct 2025 10:59:47 +0200
Subject: [PATCH] Remove quotes.txt

Signed-off-by: John Doe <john.doe@email.com>
---
quotes.txt | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 quotes.txt

diff --git a/quotes.txt b/quotes.txt
deleted file mode 100644
index 22174d6b96bbdd674d38f8be446d22758f996aba..0000000000000000000000000000000000000000
--- a/quotes.txt
+++ /dev/null
@@ -1 +0,0 @@
-Si vis pacem cole justitiam.
--
2.51.0
19 changes: 19 additions & 0 deletions tests/patchformat/update.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
From 3360e00554544de3a68a227ac9eff5bb687da723 Mon Sep 17 00:00:00 2001
From: John Doe <john.doe@email.com>
Date: Wed, 1 Oct 2025 10:59:37 +0200
Subject: [PATCH] Update quote

Signed-off-by: John Doe <john.doe@email.com>
---
quotes.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/quotes.txt b/quotes.txt
index edcfcc5846847fffa4986b8437f1d7a3bd8aa8cf..22174d6b96bbdd674d38f8be446d22758f996aba 100644
--- a/quotes.txt
+++ b/quotes.txt
@@ -1 +1 @@
-habita fides ipsam plerumque obligat fidem.
+Si vis pacem cole justitiam.
--
2.51.0
41 changes: 41 additions & 0 deletions tests/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,47 @@ def test_pathstrip(self):
self.assertEqual(patch_ng.pathstrip(b'path/name.diff', 1), b'name.diff')
self.assertEqual(patch_ng.pathstrip(b'path/name.diff', 0), b'path/name.diff')


class TestPatchFormat(unittest.TestCase):
def setUp(self):
self.save_cwd = os.getcwd()
self.tmpdir = mkdtemp(prefix=self.__class__.__name__)
shutil.copytree(join(TESTS, 'patchformat'), join(self.tmpdir, 'patchformat'))

def tearDown(self):
os.chdir(self.save_cwd)
remove_tree_force(self.tmpdir)

def test_handle_full_index_patch_format(self):
"""Test that a full index patch format is handled correctly

When parsing a git patch with a full index line (40 hex chars),
the patch type should be detected as GIT and the patch should be
applied correctly (create, update, remove a file).
"""

os.chdir(self.tmpdir)
pto = patch_ng.fromfile(join(self.tmpdir, 'patchformat', 'create.patch'))
self.assertEqual(len(pto), 1)
self.assertEqual(pto.items[0].type, patch_ng.GIT)
self.assertTrue(pto.apply())
self.assertTrue(os.path.exists(join(self.tmpdir, 'quotes.txt')))

pto = patch_ng.fromfile(join(self.tmpdir, 'patchformat', 'update.patch'))
self.assertEqual(len(pto), 1)
self.assertEqual(pto.items[0].type, patch_ng.GIT)
self.assertTrue(pto.apply())
with open(join(self.tmpdir, 'quotes.txt'), 'rb') as f:
content = f.read()
self.assertTrue(b'Si vis pacem cole justitiam.' in content)

pto = patch_ng.fromfile(join(self.tmpdir, 'patchformat', 'remove.patch'))
self.assertEqual(len(pto), 1)
self.assertEqual(pto.items[0].type, patch_ng.GIT)
self.assertTrue(pto.apply())
self.assertFalse(os.path.exists(join(self.tmpdir, 'quotes.txt')))


def remove_tree_force(folder):
for root, _, files in os.walk(folder):
for it in files:
Expand Down