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