fix dwim for reversed patches
authorop <op@openbsd.org>
Wed, 3 Aug 2022 07:25:44 +0000 (07:25 +0000)
committerop <op@openbsd.org>
Wed, 3 Aug 2022 07:25:44 +0000 (07:25 +0000)
patch(1) fails to recognize the reversal application of a patch that
cerates a file.  since an empty context always matches, the idea is to
run the dwim ("do what I mean") code also when locate_hunk succeeds but
the patch would create a file and the match is on the first line.
fixes the (disabled) test t3.

ok stsp@

usr.bin/patch/patch.c

index 1d9070b..00f9e3f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: patch.c,v 1.69 2019/12/02 22:17:32 jca Exp $  */
+/*     $OpenBSD: patch.c,v 1.70 2022/08/03 07:25:44 op Exp $   */
 
 /*
  * patch - a program to apply diffs to original files
@@ -260,7 +260,8 @@ main(int argc, char *argv[])
                        if (!skip_rest_of_patch) {
                                do {
                                        where = locate_hunk(fuzz);
-                                       if (hunk == 1 && where == 0 && !force) {
+                                       if ((hunk == 1 && where == 0 && !force) ||
+                                           (where == 1 && pch_ptrn_lines() == 0 && !force)) {
                                                /* dwim for reversed patch? */
                                                if (!pch_swap()) {
                                                        if (fuzz == 0)
@@ -276,6 +277,10 @@ main(int argc, char *argv[])
                                                                /* put it back to normal */
                                                                fatal("lost hunk on alloc error!\n");
                                                        reverse = !reverse;
+
+                                                       /* restore position if this patch creates a file */
+                                                       if (pch_ptrn_lines() == 0)
+                                                               where = 1;
                                                } else if (noreverse) {
                                                        if (!pch_swap())
                                                                /* put it back to normal */