Download raw body.
got patch: resolve paths from $PWD
On Fri, Apr 22, 2022 at 10:58:54PM +0200, Omar Polo wrote:
> The paths are computed in worktree.c:got_worktree_patch_check_path via
> patch_check_path, and they're build off got_worktree_resolve_path.
>
> I'm still keeping the paths relative to the worktree root in the
> pathlists, otherwise I'd broke everything. I'm then building (again)
> the absolute paths in apply_patch before running the patch machinery.
>
> I'm only feeding absolute paths to lstat/fopen/rename & co.
> Yes. To be fair it could be somehow avoided right now, I just need to
> propagate the path I build in worktree.c:patch_check_path up until
> apply_patch. (it's the "ondisk_path" from patch_check_path). but that
> can be done in a follow-up commit, diff belows already has three
> different fixes, it's probably enough ;)
This seems great. ok stsp@
> diff refs/heads/main refs/heads/ppath2
> blob - 9b49b4b1349c2d2994dfa6e667c9265975aea642
> 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",
> @@ -612,7 +625,7 @@ apply_patch(struct got_worktree *worktree, struct got_
> }
>
> if (fchmod(fileno(tmp), mode) == -1) {
> - err = got_error_from_errno2("chmod", newpath);
> + err = got_error_from_errno2("chmod", tmppath);
> goto done;
> }
>
> @@ -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 - bfebb46526cc0f3f0deda90d0868edad7c6946c9
> blob + bbe95ae655a519c5a9d4dc6eac25f7ace38c7452
> --- lib/worktree.c
> +++ lib/worktree.c
> @@ -8795,7 +8795,8 @@ patch_check_path(const char *p, char **path, unsigned
> ie = got_fileindex_entry_get(fileindex, *path, strlen(*path));
> if (ie) {
> *staged_status = get_staged_status(ie);
> - err = get_file_status(status, &sb, ie, *path, -1, NULL, repo);
> + err = get_file_status(status, &sb, ie, ondisk_path, -1, NULL,
> + repo);
> if (err)
> goto done;
> } else {
> blob - b3f10d2dc6e282f6548c695befab125a7f8f680e
> blob + af1fd72e33001d46b8f822e0b0a7f00a5b1ad7b7
> --- regress/cmdline/patch.sh
> +++ regress/cmdline/patch.sh
> @@ -1273,6 +1273,46 @@ EOF
> 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
>
>
>
got patch: resolve paths from $PWD