subtree: validate --prefix against commit in split
git subtree split currently validates --prefix against the working tree. This breaks when splitting an older commit or when the working tree does not contain the subtree, even though the commit does. For example: git subtree split --prefix=pkg <commit> fails if pkg was removed later, even though it exists in <commit>. Fix this by validating the prefix against the specified commit using git cat-file instead of the working tree. Add a test to ensure this behavior does not regress. Signed-off-by: Pushkar Singh <pushkarkumarsingh1970@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pushkar Singh committed
Feb 3, 2026 at 16:48 UTC
a606fcdceb807b93013542e5e4d5f4c233aa6c83
2 files changed
+31
contrib/subtree/git-subtree.sh
+9
@@ -257,6 +257,9 @@ main () {
257
test -e "$arg_prefix" &&
258
die "fatal: prefix '$arg_prefix' already exists."
259
;;
260
+ split)
261
+ # checked later against the commit, not the working tree
262
+ ;;
263
*)
264
test -e "$arg_prefix" ||
265
die "fatal: '$arg_prefix' does not exist; use 'git subtree add'"
@@ -966,6 +969,12 @@ cmd_split () {
969
else
970
die "fatal: you must provide exactly one revision, and optionally a repository. Got: '$*'"
971
fi
972
+
973
+ # Now validate prefix against the commit, not the working tree
974
+ if ! git cat-file -e "$rev:$dir" 2>/dev/null
975
+ then
976
+ die "fatal: '$dir' does not exist; use 'git subtree add'"
977
+ fi
978
repository=""
979
if test "$#" = 2
980
then
contrib/subtree/t/t7900-subtree.sh
+22
@@ -368,6 +368,28 @@ test_expect_success 'split requires path given by option --prefix must exist' '
368
)
369
'
370
371
+test_expect_success 'split works when prefix exists in commit but not in working tree' '
372
+ subtree_test_create_repo "$test_count" &&
373
+ (
374
+ cd "$test_count" &&
375
+
376
+ # create subtree
377
+ mkdir pkg &&
378
+ echo ok >pkg/file &&
379
+ git add pkg &&
380
+ git commit -m "add pkg" &&
381
+ good=$(git rev-parse HEAD) &&
382
+
383
+ # remove it from working tree in later commit
384
+ git rm -r pkg &&
385
+ git commit -m "remove pkg" &&
386
+
387
+ # must still be able to split using the old commit
388
+ git subtree split --prefix=pkg "$good" >out &&
389
+ test -s out
390
+ )
391
+'
392
+
393
test_expect_success 'split rejects flags for add' '
394
subtree_test_create_repo "$test_count" &&
395
subtree_test_create_repo "$test_count/sub proj" &&