** Description changed:

  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
+  alpha
  -bravo
  +BRAVO
-  charlie
+  charlie
  diff --git a/two.txt b/two.txt
  index 0000003..0000004 100644
  --- a/two.txt
  +++ b/two.txt
  @@ -1,3 +1,3 @@
-  delta
+  delta
  -echo
  +ECHO
-  foxtrot
+  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 
+ /tmp/pc
  $ grep -c BRAVO one.txt   # 0: first diff was not applied
  0
  
- /tmp/pc 
+ /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:906). The main loop's increment,
+ (src/patch.c:913). The main loop's increment,
  reinitialize_almost_everything(), resets diff_type = NO_DIFF after every
- patch (src/patch.c:199, :710), so the forced type governs only the first
+ 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.

-- 
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

Reply via email to