Commit 7a30b5cb05817b97fcb91183049b629a948e3ba6

Omar Polo 2022-03-20T08:54:45

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

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