got patch: prefer new name if not /dev/null and not a git-style diff This fixes a common issue when for e.g. generating patches with $ diff -u foo.orig foo where 'got patch' failed because 'foo.orig' has an 'unexpected status'. prodded by naddy, ok stsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
diff --git a/libexec/got-read-patch/got-read-patch.c b/libexec/got-read-patch/got-read-patch.c
index deb0e81..6e96334 100644
--- a/libexec/got-read-patch/got-read-patch.c
+++ b/libexec/got-read-patch/got-read-patch.c
@@ -60,14 +60,21 @@
struct imsgbuf ibuf;
static const struct got_error *
-send_patch(const char *oldname, const char *newname)
+send_patch(const char *oldname, const char *newname, int git)
{
struct got_imsg_patch p;
memset(&p, 0, sizeof(p));
- if (oldname != NULL)
+ /*
+ * Prefer the new name if it's not /dev/null and it's not
+ * a git-style diff.
+ */
+ if (!git && newname != NULL && oldname != NULL)
+ strlcpy(p.old, newname, sizeof(p.old));
+ else if (oldname != NULL)
strlcpy(p.old, oldname, sizeof(p.old));
+
if (newname != NULL)
strlcpy(p.new, newname, sizeof(p.new));
@@ -169,7 +176,7 @@ find_patch(FILE *fp)
(!create && old == NULL))
err = got_error(GOT_ERR_PATCH_MALFORMED);
else
- err = send_patch(old, new);
+ err = send_patch(old, new, git);
if (err)
break;
diff --git a/regress/cmdline/patch.sh b/regress/cmdline/patch.sh
index 32c8529..7be41fc 100755
--- a/regress/cmdline/patch.sh
+++ b/regress/cmdline/patch.sh
@@ -647,8 +647,9 @@ test_patch_rename() {
fi
cat <<EOF > $testroot/wt/patch
---- alpha
-+++ eta
+diff --git a/alpha b/eta
+--- a/alpha
++++ b/eta
@@ -0,0 +0,0 @@
EOF
@@ -700,8 +701,9 @@ EOF
rm $testroot/wt/eta
cat <<EOF > $testroot/wt/patch
---- alpha
-+++ eta
+diff --git a/alpha b/eta
+--- a/alpha
++++ b/eta
@@ -1 +1,2 @@
alpha
+but now is eta
@@ -863,6 +865,7 @@ test_patch_nop() {
+++ /dev/null
@@ -1 +0,0 @@
-beta
+diff --git a/gamma/delta b/gamma/delta.new
--- gamma/delta
+++ gamma/delta.new
@@ -1 +1 @@
@@ -1048,6 +1051,40 @@ EOF
test_done $testroot $ret
}
+test_patch_prefer_new_path() {
+ local testroot=`test_init patch_orig`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ test_done $testroot $ret
+ return 1
+ fi
+
+ cat <<EOF > $testroot/wt/patch
+--- alpha.orig
++++ alpha
+@@ -1 +1,2 @@
+ alpha
++was edited
+EOF
+
+ (cd $testroot/wt && got patch patch) > $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ test_done $testroot $ret
+ return 1
+ fi
+
+ echo 'M alpha' > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done $testroot $ret
+}
+
test_parseargs "$@"
run_test test_patch_simple_add_file
run_test test_patch_simple_rm_file
@@ -1066,3 +1103,4 @@ run_test test_patch_nop
run_test test_patch_preserve_perm
run_test test_patch_create_dirs
run_test test_patch_with_offset
+run_test test_patch_prefer_new_path