At some point in the past few years, patch stopped replacing files which were not modified due to all hunks failing to apply. This breaks the following pattern:
$ cp -al package package-orig $ cd package $ patch -p1 </tmp/package-fixes.diff 1 out of 1 hunk FAILED -- saving rejects to file foo.c.rej $ emacs foo.c{,.rej} # apply them manually $ rm foo.c.{orig,rej} $ cd .. $ diff -urN package{-orig,} $ # huh, no diffs? ...because patch leaves the original (hardlinked) file untouched when it detects that all hunks have failed. This is particularly annoying since it means patch's behavior is not consistent with respect to hard links: patch _does_ delink and replace files if some, but not all, hunks fail to apply. As a result, I have to check each file I intend to edit and manually "cp foo foo~; mv foo~ foo" if the file has not been modified. The patch below fixes this behavior. I've deliberately left the indentation alone to highlight the actual functional changes. --Andrew Church http://achurch.org/ diff -urN patch-2.7.5-orig/src/patch.c patch-2.7.5/src/patch.c --- patch-2.7.5-orig/src/patch.c 2015-03-07 09:34:20 +0900 +++ patch-2.7.5/src/patch.c 2015-06-01 18:03:57 +0900 @@ -554,10 +554,6 @@ mode_t new_mode = pch_mode (! reverse); bool set_mode = new_mode && old_mode != new_mode; - /* Avoid replacing files when nothing has changed. */ - if (failed < hunk || diff_type == ED_DIFF || set_mode - || pch_copy () || pch_rename ()) - { enum file_attributes attr = 0; struct timespec new_time = pch_timestamp (! reverse); mode_t mode = file_type | @@ -599,10 +595,6 @@ if (pch_rename ()) output_file (NULL, NULL, NULL, inname, &instat, mode, backup); - } - else - output_file (outname, NULL, &tmpoutst, NULL, NULL, - file_type | 0, backup); } } }