Public bug reported:
Versions tested: patch 2.7.6 and 2.8 (identical behavior)
When -c (--context) is given and the input is a git-format unified diff,
patch discards the entire first file-level diff without applying any of
its hunks, prints no warning, and exits 0. In a multi-diff input, all
diffs after the first are then auto-detected as unified and applied
normally, so the result is a silent, partial application reported as
complete success.
== Reproducer ==
mkdir /tmp/pc && cd /tmp/pc
printf 'alpha\nbravo\ncharlie\n' > one.txt
printf 'delta\necho\nfoxtrot\n' > two.txt
cat > repro.patch << 'PATCH'
diff --git a/one.txt b/one.txt
index 0000001..0000002 100644
--- a/one.txt
+++ b/one.txt
@@ -1,3 +1,3 @@
alpha
-bravo
+BRAVO
charlie
diff --git a/two.txt b/two.txt
index 0000003..0000004 100644
--- a/two.txt
+++ b/two.txt
@@ -1,3 +1,3 @@
delta
-echo
+ECHO
foxtrot
PATCH
patch -p1 -c -t --verbose -i repro.patch; echo "exit: $?"
grep -c BRAVO one.txt # 0: first diff was not applied
grep -c ECHO two.txt # 1: second diff was applied
== Output ==
patch -p1 -c -t --verbose -i demo.patch; echo "exit: $?"
Hmm... Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|diff --git a/one.txt b/one.txt
|index 0000001..0000002 100644
|--- a/one.txt
|+++ b/one.txt
|@@ -1,3 +1,3 @@
| alpha
|-bravo
|+BRAVO
| charlie
--------------------------
patching file one.txt
Hmm... The next patch looks like a unified diff to me...
The text leading up to this was:
--------------------------
|diff --git a/two.txt b/two.txt
|index 0000003..0000004 100644
|--- a/two.txt
|+++ b/two.txt
--------------------------
patching file two.txt
Hunk #1 succeeded at 1.
done
exit: 0
/tmp/pc
$ grep -c BRAVO one.txt # 0: first diff was not applied
0
/tmp/pc
$ grep -c ECHO two.txt # 1: second diff was applied
1
== Expectation ==
A diagnostic and a nonzero exit status indicate that recognizable hunks
were discarded because they did not match the format forced on the
command line.
== Analysis ==
This appears to have been broken since "diff --git" format support was
added in 2.7.
-c sets diff_type = CONTEXT_DIFF once at option parsing
(src/patch.c:913). The main loop's increment,
reinitialize_almost_everything(), resets diff_type = NO_DIFF after every
patch (src/patch.c:199, :717), so the forced type governs only the first
diff. The later diffs are auto-detected, which is why they apply.
Edit: updated line numbers to match Noble's 2.7.6-7build3 source.
** Affects: patch (Ubuntu)
Importance: Undecided
Status: New
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2163450
Title:
forced format (-c) silently discards the first hunk of a unified diff
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/patch/+bug/2163450/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs