aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoaquim Rocha <joaquim@amutable.com>2026-02-18 00:15:32 +0000
committerJunio C Hamano <gitster@pobox.com>2026-02-20 10:12:58 -0800
commit0fbf380daf1367a5c203eb25b744f55634dab251 (patch)
tree448cf3580b38fe07614f776fb05d50d1f0e39976
parent9a2fb147f2c61d0cab52c883e7e26f5b7948e3ed (diff)
downloadgit-0fbf380daf1367a5c203eb25b744f55634dab251.tar.xz
apply: normalize path in --directory argument
When passing a relative path like --directory=./some/sub, the leading "./" caused apply to prepend it literally to patch filenames, resulting in an error (invalid path). There may be more cases like this where users pass some/./path to the directory which can easily be normalized to an acceptable path, so these changes try to normalize the path before using it. Signed-off-by: Joaquim Rocha <joaquim@amutable.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--apply.c4
-rwxr-xr-xt/t4128-apply-root.sh41
2 files changed, 45 insertions, 0 deletions
diff --git a/apply.c b/apply.c
index a2ceb3fb40..7c07d124f4 100644
--- a/apply.c
+++ b/apply.c
@@ -4963,6 +4963,10 @@ static int apply_option_parse_directory(const struct option *opt,
strbuf_reset(&state->root);
strbuf_addstr(&state->root, arg);
+
+ if (strbuf_normalize_path(&state->root) < 0)
+ return error(_("unable to normalize directory: '%s'"), arg);
+
strbuf_complete(&state->root, '/');
return 0;
}
diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh
index f6db5a79dd..5eba15fa66 100755
--- a/t/t4128-apply-root.sh
+++ b/t/t4128-apply-root.sh
@@ -43,6 +43,47 @@ test_expect_success 'apply --directory -p (2) ' '
'
+test_expect_success 'apply --directory (./ prefix)' '
+ git reset --hard initial &&
+ git apply --directory=./some/sub -p3 --index patch &&
+ echo Bello >expect &&
+ git show :some/sub/dir/file >actual &&
+ test_cmp expect actual &&
+ test_cmp expect some/sub/dir/file
+'
+
+test_expect_success 'apply --directory (double slash)' '
+ git reset --hard initial &&
+ git apply --directory=some//sub -p3 --index patch &&
+ echo Bello >expect &&
+ git show :some/sub/dir/file >actual &&
+ test_cmp expect actual &&
+ test_cmp expect some/sub/dir/file
+'
+
+test_expect_success 'apply --directory (./ in the middle)' '
+ git reset --hard initial &&
+ git apply --directory=some/./sub -p3 --index patch &&
+ echo Bello >expect &&
+ git show :some/sub/dir/file >actual &&
+ test_cmp expect actual &&
+ test_cmp expect some/sub/dir/file
+'
+
+test_expect_success 'apply --directory (../ in the middle)' '
+ git reset --hard initial &&
+ git apply --directory=some/../some/sub -p3 --index patch &&
+ echo Bello >expect &&
+ git show :some/sub/dir/file >actual &&
+ test_cmp expect actual &&
+ test_cmp expect some/sub/dir/file
+'
+
+test_expect_success 'apply --directory rejects leading ../' '
+ test_must_fail git apply --directory=../foo -p3 patch 2>err &&
+ test_grep "unable to normalize directory" err
+'
+
cat > patch << EOF
diff --git a/newfile b/newfile
new file mode 100644