diff --git a/Makefile.am b/Makefile.am index 7e401dad..98c337b9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -228,6 +228,7 @@ TESTS = tests/newline1/run-test \ tests/recount5/run-test \ tests/recount6/run-test \ tests/recount7/run-test \ + tests/recount8/run-test \ tests/unwrapdiff1/run-test \ tests/overstrip/run-test \ tests/context1/run-test \ diff --git a/NEWS b/NEWS index a7f61c24..f2595a8d 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,12 @@ Patchutils news processing patches with multiple files, breaking the patch format. Addresses GitHub issue #48. + Fixed recountdiff corruption of new file headers when git signature + lines are present. Previously, recountdiff would incorrectly change + "@@ -0,0 +1,N @@" to "@@ -1 +1,N @@" for new files in patches containing + git signature lines (e.g., "-- \n2.50.1"), causing patch application + to fail. Addresses GitHub issue #49. + 0.4.2 (stable) Build system improvements: only run xmlto once during documentation diff --git a/scripts/recountdiff.in b/scripts/recountdiff.in index 3bbcf2d6..ca221c4e 100755 --- a/scripts/recountdiff.in +++ b/scripts/recountdiff.in @@ -77,6 +77,10 @@ while ($i < $#line) { my $spit = 0; if (/^\s/ or /^$/) { $orig++; $new++; } elsif (/^\+/) { $new++; } + elsif (/^-- $/) { + # Git signature line - end of patch content + $spit = 1; + } elsif (/^-/) { # Look out for new file changes. if (/^--- /) { @@ -125,17 +129,33 @@ foreach (@off_lines) { next; } $line[$_] =~ /^@@ -(\d+),?(\d+)? \+(\d+),?(\d+)? @@(.*)$/; - ($ooff,$oc,$nc,$misc) = ($1,$2,$4,$5); - $oc = 1 unless defined($oc); + ($ooff,$oc,$noff_orig,$nc,$misc) = ($1,$2,$3,$4,$5); + + # Check for new file before applying defaults + $is_new_file = ($ooff == 0 && defined($oc) && $oc == 0); + + # For new files, preserve oc=0; otherwise apply default + if (!$is_new_file) { + $oc = 1 unless defined($oc); + } $nc = 1 unless defined($nc); - $noff = $ooff + $offset; - $noff++ if ($oc == 0); - $noff-- if ($nc == 0); + + # For new files (ooff=0, original oc=0), preserve the original new offset + if ($is_new_file) { + $noff = $noff_orig + $offset; + } else { + $noff = $ooff + $offset; + # Don't adjust offset for new files (when ooff is 0 and oc is 0) + $noff++ if ($oc == 0 && $ooff != 0); + $noff-- if ($nc == 0); + } $line[$_] = "@@ -$ooff"; $line[$_] .= ",$oc" if ($oc != 1); $line[$_] .= " +$noff"; $line[$_] .= ",$nc" if ($nc != 1); $line[$_] .= " @@" . "$misc\n"; + + $offset += $nc - $oc; } diff --git a/tests/recount8/run-test b/tests/recount8/run-test new file mode 100755 index 00000000..77f27ec8 --- /dev/null +++ b/tests/recount8/run-test @@ -0,0 +1,37 @@ +#!/bin/sh + +# This is a recountdiff(1) testcase. +# Test: Fix bug with new files when git signature lines are present (issue #49). + +. ${top_srcdir-.}/tests/common.sh + +cat <<"EOF" > patch +diff --git a/test_file b/test_file +new file mode 100644 +index 0000000..83db48f +--- /dev/null ++++ b/test_file +@@ -0,0 +1,3 @@ ++line1 ++line2 ++line3 +-- +2.50.1 + +EOF + +${RECOUNTDIFF} patch > patch-recounted || exit 1 +cat <<"EOF" | cmp - patch-recounted || exit 1 +diff --git a/test_file b/test_file +new file mode 100644 +index 0000000..83db48f +--- /dev/null ++++ b/test_file +@@ -0,0 +1,3 @@ ++line1 ++line2 ++line3 +-- +2.50.1 + +EOF