Commit Diff


commit - c17f3d0c7b2d780dbb8117b66d797c92c1f4add3
commit + 8afe1f716136923060b5d7e0838397460b2a4e20
blob - fc2a6b831e2b155e6d48a9bd8de4bf8787c1ff3f
blob + 4fe53af57ea2ca7cae58421b0f402875b1fda7a0
--- libexec/got-read-patch/got-read-patch.c
+++ libexec/got-read-patch/got-read-patch.c
@@ -122,14 +122,14 @@ filename(const char *at, char **name)
 }
 
 static const struct got_error *
-find_patch(FILE *fp)
+find_patch(int *empty, FILE *fp)
 {
 	const struct got_error *err = NULL;
 	char	*old = NULL, *new = NULL;
 	char	*line = NULL;
 	size_t	 linesize = 0;
 	ssize_t	 linelen;
-	int	 create, git = 0;
+	int	 create, rename = 0, git = 0;
 
 	while ((linelen = getline(&line, &linesize, fp)) != -1) {
 		/*
@@ -140,14 +140,33 @@ find_patch(FILE *fp)
 		if (!strncmp(line, "--- ", 4)) {
 			free(old);
 			err = filename(line+4, &old);
+		} else if (rename && !strncmp(line, "rename from ", 12)) {
+			free(old);
+			err = filename(line+12, &old);
 		} else if (!strncmp(line, "+++ ", 4)) {
 			free(new);
 			err = filename(line+4, &new);
-		} else if (!strncmp(line, "diff --git a/", 13))
+		} else if (rename && !strncmp(line, "rename to ", 10)) {
+			free(new);
+			err = filename(line + 10, &new);
+		} else if (git && !strncmp(line, "similarity index 100%", 21))
+			rename = 1;
+		else if (!strncmp(line, "diff --git a/", 13))
 			git = 1;
 
 		if (err)
+			break;
+
+		/*
+		 * Git-style diffs with "similarity index 100%" don't
+		 * have any hunks and ends with the "rename to foobar"
+		 * line.
+		 */
+		if (rename && old != NULL && new != NULL) {
+			*empty = 1;
+			err = send_patch(old, new, git);
 			break;
+		}
 
 		if (!strncmp(line, "@@ -", 4)) {
 			create = !strncmp(line+4, "0,0", 3);
@@ -411,7 +430,7 @@ read_patch(struct imsgbuf *ibuf, int fd)
 {
 	const struct got_error *err = NULL;
 	FILE *fp;
-	int ok, patch_found = 0;
+	int patch_found = 0;
 
 	if ((fp = fdopen(fd, "r")) == NULL) {
 		err = got_error_from_errno("fdopen");
@@ -420,16 +439,19 @@ read_patch(struct imsgbuf *ibuf, int fd)
 	}
 
 	while (!feof(fp)) {
-		err = find_patch(fp);
+		int empty = 0, ok = 1;
+
+		err = find_patch(&empty, fp);
 		if (err)
 			goto done;
 
 		patch_found = 1;
 		for (;;) {
-			err = parse_hunk(fp, &ok);
+			if (!empty)
+				err = parse_hunk(fp, &ok);
 			if (err)
 				goto done;
-			if (!ok) {
+			if (!ok || empty) {
 				err = send_patch_done();
 				if (err)
 					goto done;
blob - 43981599f51928fd929e8cc47538da750b875b97
blob + b30e9e02052c205e40d442f72d8988369b6eea06
--- regress/cmdline/patch.sh
+++ regress/cmdline/patch.sh
@@ -647,14 +647,22 @@ test_patch_rename() {
 	fi
 
 	cat <<EOF > $testroot/wt/patch
+diff --git a/beta b/iota
+similarity index 100%
+rename from beta
+rename to iota
 diff --git a/alpha b/eta
 --- a/alpha
 +++ b/eta
-@@ -0,0 +0,0 @@
+@@ -1 +1 @@
+-alpha
++eta
 EOF
 
-	echo 'D  alpha' > $testroot/stdout.expected
-	echo 'A  eta'  >> $testroot/stdout.expected
+	echo 'D  beta'   > $testroot/stdout.expected
+	echo 'A  iota'  >> $testroot/stdout.expected
+	echo 'D  alpha' >> $testroot/stdout.expected
+	echo 'A  eta'   >> $testroot/stdout.expected
 
 	(cd $testroot/wt && got patch patch) > $testroot/stdout
 	ret=$?
@@ -671,77 +679,35 @@ EOF
 		return 1
 	fi
 
-	if [ -f $testroot/wt/alpha ]; then
-		echo "alpha was not removed" >&2
+	if [ -f $testroot/wt/alpha -o -f $testroot/wt/beta ]; then
+		echo "alpha or beta were not removed" >&2
 		test_done $testroot 1
 		return 1
 	fi
-	if [ ! -f $testroot/wt/eta ]; then
-		echo "eta was not created" >&2
+	if [ ! -f $testroot/wt/iota -o ! -f $testroot/wt/eta ]; then
+		echo "iota or eta were not created" >&2
 		test_done $testroot 1
 		return 1
 	fi
 
-	echo alpha > $testroot/wt/eta.expected
-	cmp -s $testroot/wt/eta.expected $testroot/wt/eta
-	ret=$?
-	if [ $ret -ne 0 ]; then
-		diff -u $testroot/wt/eta.expected $testroot/wt/eta
-		test_done $testroot $ret
-		return 1
-	fi
-
-	# revert the changes and try again with a rename + edit
-	(cd $testroot/wt && got revert alpha eta) > /dev/null
-	ret=$?
-	if [ $ret -ne 0 ]; then
-		test_done $testroot $ret
-		return 1
-	fi
-	rm $testroot/wt/eta
-
-	cat <<EOF > $testroot/wt/patch
-diff --git a/alpha b/eta
---- a/alpha
-+++ b/eta
-@@ -1 +1,2 @@
- alpha
-+but now is eta
-EOF
-
-	(cd $testroot/wt && got patch patch) > $testroot/stdout
+	echo beta > $testroot/wt/iota.expected
+	cmp -s $testroot/wt/iota.expected $testroot/wt/iota
 	ret=$?
 	if [ $ret -ne 0 ]; then
+		diff -u $testroot/wt/iota.expected $testroot/wt/iota
 		test_done $testroot $ret
 		return 1
 	fi
 
-	cmp -s $testroot/stdout.expected $testroot/stdout
+	echo eta > $testroot/wt/eta.expected
+	cmp -s $testroot/wt/eta.expected $testroot/wt/eta
 	ret=$?
 	if [ $ret -ne 0 ]; then
-		diff -u $testroot/stdout.expected $testroot/stdout
+		diff -u $testroot/wt/eta.expected $testroot/wt/eta
 		test_done $testroot $ret
 		return 1
 	fi
 
-	if [ -f $testroot/wt/alpha ]; then
-		echo "alpha was not removed" >&2
-		test_done $testroot 1
-		return 1
-	fi
-	if [ ! -f $testroot/wt/eta ]; then
-		echo "eta was not created" >&2
-		test_done $testroot 1
-		return 1
-	fi
-
-	echo alpha > $testroot/wt/eta.expected
-	echo 'but now is eta' >> $testroot/wt/eta.expected
-	cmp -s $testroot/wt/eta.expected $testroot/wt/eta
-	ret=$?
-	if [ $ret -ne 0 ]; then
-		diff -u $testroot/wt/eta.expected $testroot/wt/eta
-	fi
 	test_done $testroot $ret
 }