summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2012-07-30 16:47:28 +0200
committerAndreas Gruenbacher <agruen@linbit.com>2012-08-01 04:28:07 +0200
commit6be1a126bdadcc84a2d4086e4d4d80b040786230 (patch)
tree26e4faa3c55ec3d2546f15284b8bcedfc598583a
parent57eb3007ab9cb7ee732c8edcea3195c512b8042f (diff)
downloadpatch-6be1a126bdadcc84a2d4086e4d4d80b040786230.tar.gz
Try to recognize concatenated git diffs and handle them appropriately
* src/patch.c (main): Remember the "before" SHA1 hashes of git-style patches; the same patch will always use the same "before" SHA1 for a specific file. Try to recognize concatenated patches based on that. * tests/concat-git-diff: New test case. * tests/Makefile.am (TESTS): Add new test case.
-rw-r--r--src/patch.c25
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/concat-git-diff41
3 files changed, 67 insertions, 0 deletions
diff --git a/src/patch.c b/src/patch.c
index ae6d0b6..2d6443a 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -245,6 +245,31 @@ main (int argc, char **argv)
}
}
+ if (pch_git_diff () && ! skip_rest_of_patch && ! inerrno)
+ {
+ /* Try to recognize concatenated git diffs based on the SHA1 hashes
+ in the headers. Will not always succeed for patches that rename
+ or copy files. */
+
+ char const *previous_sha1 = lookup_sha1 (&instat);
+
+ if (previous_sha1)
+ {
+ char const *sha1 = pch_sha1 (reverse);
+
+ for (; *previous_sha1 && *sha1; previous_sha1++, sha1++)
+ if (*previous_sha1 != *sha1)
+ break;
+ if (*previous_sha1 && *sha1)
+ {
+ output_files (&instat);
+ update_sha1 (&instat, pch_sha1 (reverse));
+ }
+ }
+ else
+ update_sha1 (&instat, pch_sha1 (reverse));
+ }
+
if (read_only_behavior != RO_IGNORE
&& ! inerrno && ! S_ISLNK (instat.st_mode)
&& access (inname, W_OK) != 0)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index fba38b0..02fc6de 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -20,6 +20,7 @@ TESTS = \
asymmetric-hunks \
backup-prefix-suffix \
bad-filenames \
+ concat-git-diff \
copy-rename \
corrupt-reject-files \
create-delete \
diff --git a/tests/concat-git-diff b/tests/concat-git-diff
new file mode 100644
index 0000000..3bc48ed
--- /dev/null
+++ b/tests/concat-git-diff
@@ -0,0 +1,41 @@
+# Copyright (C) 2010-2012 Free Software Foundation, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# in any medium, are permitted without royalty provided the copyright
+# notice and this notice are preserved.
+
+. $srcdir/test-lib.sh
+
+require_cat
+use_local_patch
+use_tmpdir
+
+# ==============================================================
+
+ncheck 'echo one > f'
+
+cat > concatenated.diff <<EOF
+diff --git a/f b/f
+index 5626abf..f719efd 100644
+--- a/f
++++ b/f
+@@ -1 +1 @@
+-one
++two
+diff --git a/f b/f
+index f719efd..2bdf67a 100644
+--- a/f
++++ b/f
+@@ -1 +1 @@
+-two
++three
+EOF
+
+check 'patch -p1 < concatenated.diff || echo "Status: $?"' <<EOF
+patching file f
+patching file f
+EOF
+
+check 'cat f' <<EOF
+three
+EOF