Commit Diff


commit - a05fb46091635af3b96b8f49a21517bbbb38fa84
commit + ed3bff83077bfa3c251eb87bc83f541d8cdaaa11
blob - 98418089797d2253ab063b1a54e7cd5043491334
blob + adf9459c88ef262d9070733fe62620364926f5db
--- lib/patch.c
+++ lib/patch.c
@@ -565,13 +565,14 @@ patch_add(void *arg, unsigned char status, const char 
 
 static const struct got_error *
 apply_patch(struct got_worktree *worktree, struct got_repository *repo,
-    const char *oldpath, const char *newpath, struct got_patch *p,
-    int nop, struct patch_args *pa, got_cancel_cb cancel_cb, void *cancel_arg)
+    const char *old, const char *new, struct got_patch *p, int nop,
+    struct patch_args *pa, got_cancel_cb cancel_cb, void *cancel_arg)
 {
 	const struct got_error *err = NULL;
 	struct got_pathlist_head oldpaths, newpaths;
 	struct got_pathlist_entry *pe;
 	int file_renamed = 0;
+	char *oldpath = NULL, *newpath = NULL;
 	char *tmppath = NULL, *template = NULL, *parent = NULL;;
 	FILE *tmp = NULL;
 	mode_t mode = GOT_DEFAULT_FILE_MODE;
@@ -579,13 +580,25 @@ apply_patch(struct got_worktree *worktree, struct got_
 	TAILQ_INIT(&oldpaths);
 	TAILQ_INIT(&newpaths);
 
-	err = got_pathlist_insert(&pe, &oldpaths, oldpath, NULL);
+	err = got_pathlist_insert(&pe, &oldpaths, old, NULL);
 	if (err)
 		goto done;
-	err = got_pathlist_insert(&pe, &newpaths, newpath, NULL);
+	err = got_pathlist_insert(&pe, &newpaths, new, NULL);
 	if (err)
+		goto done;
+
+	if (asprintf(&oldpath, "%s/%s", got_worktree_get_root_path(worktree),
+	    old) == -1) {
+		err = got_error_from_errno("asprintf");
 		goto done;
+	}
 
+	if (asprintf(&newpath, "%s/%s", got_worktree_get_root_path(worktree),
+	    new) == -1) {
+		err = got_error_from_errno("asprintf");
+		goto done;
+	}
+
 	file_renamed = strcmp(oldpath, newpath);
 
 	if (asprintf(&template, "%s/got-patch",
@@ -650,8 +663,7 @@ apply_patch(struct got_worktree *worktree, struct got_
 		if (err)
 			unlink(newpath);
 	} else
-		err = report_progress(pa, oldpath, newpath, GOT_STATUS_MODIFY,
-		    NULL);
+		err = report_progress(pa, old, new, GOT_STATUS_MODIFY, NULL);
 
 done:
 	got_pathlist_free(&oldpaths);
@@ -661,6 +673,8 @@ done:
 	if (tmppath != NULL)
 		unlink(tmppath);
 	free(tmppath);
+	free(oldpath);
+	free(newpath);
 	return err;
 }
 
blob - b3f10d2dc6e282f6548c695befab125a7f8f680e
blob + af1fd72e33001d46b8f822e0b0a7f00a5b1ad7b7
--- regress/cmdline/patch.sh
+++ regress/cmdline/patch.sh
@@ -1272,7 +1272,47 @@ EOF
 	fi
 	test_done $testroot 0
 }
+
+test_patch_relative_paths() {
+	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/gamma/patch
+--- delta
++++ delta
+@@ -1 +1 @@
+-delta
++DELTA
+--- /dev/null
++++ eta
+@@ -0,0 +1 @@
++eta
+EOF
+
+	(cd $testroot/wt/gamma && got patch patch) > $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		test_done $testroot $ret
+		return 1
+	fi
+
+	echo 'M  gamma/delta' > $testroot/stdout.expected
+	echo 'A  gamma/eta' >> $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
@@ -1294,3 +1334,4 @@ run_test test_patch_with_offset
 run_test test_patch_prefer_new_path
 run_test test_patch_no_newline
 run_test test_patch_strip
+run_test test_patch_relative_paths