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>

Joaquim Rocha committed Feb 18, 2026 at 00:15 UTC 0fbf380daf1367a5c203eb25b744f55634dab251
2 files changed +45
apply.c
+4
@@ -4963,6 +4963,10 @@ static int apply_option_parse_directory(const struct option *opt,
4963
4964 strbuf_reset(&state->root);
4965 strbuf_addstr(&state->root, arg);
4966 +
4967 + if (strbuf_normalize_path(&state->root) < 0)
4968 + return error(_("unable to normalize directory: '%s'"), arg);
4969 +
4970 strbuf_complete(&state->root, '/');
4971 return 0;
4972 }
t/t4128-apply-root.sh
+41
@@ -43,6 +43,47 @@ test_expect_success 'apply --directory -p (2) ' '
43
44 '
45
46 +test_expect_success 'apply --directory (./ prefix)' '
47 + git reset --hard initial &&
48 + git apply --directory=./some/sub -p3 --index patch &&
49 + echo Bello >expect &&
50 + git show :some/sub/dir/file >actual &&
51 + test_cmp expect actual &&
52 + test_cmp expect some/sub/dir/file
53 +'
54 +
55 +test_expect_success 'apply --directory (double slash)' '
56 + git reset --hard initial &&
57 + git apply --directory=some//sub -p3 --index patch &&
58 + echo Bello >expect &&
59 + git show :some/sub/dir/file >actual &&
60 + test_cmp expect actual &&
61 + test_cmp expect some/sub/dir/file
62 +'
63 +
64 +test_expect_success 'apply --directory (./ in the middle)' '
65 + git reset --hard initial &&
66 + git apply --directory=some/./sub -p3 --index patch &&
67 + echo Bello >expect &&
68 + git show :some/sub/dir/file >actual &&
69 + test_cmp expect actual &&
70 + test_cmp expect some/sub/dir/file
71 +'
72 +
73 +test_expect_success 'apply --directory (../ in the middle)' '
74 + git reset --hard initial &&
75 + git apply --directory=some/../some/sub -p3 --index patch &&
76 + echo Bello >expect &&
77 + git show :some/sub/dir/file >actual &&
78 + test_cmp expect actual &&
79 + test_cmp expect some/sub/dir/file
80 +'
81 +
82 +test_expect_success 'apply --directory rejects leading ../' '
83 + test_must_fail git apply --directory=../foo -p3 patch 2>err &&
84 + test_grep "unable to normalize directory" err
85 +'
86 +
87 cat > patch << EOF
88 diff --git a/newfile b/newfile
89 new file mode 100644