Skip to content

Commit db6ed4f

Browse files
committed
update-index: add tests for sparse-checkout compatibility
In preparation of integrating 'git update-index' with the sparse index, introduce tests for a variety of 'git update-index' uses. Some (namely those in update-index add/remove`) are focused specifically on how 'git stash' uses 'git update-index' as a subcommand. Signed-off-by: Victoria Dye <[email protected]>
1 parent c01c8d3 commit db6ed4f

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,156 @@ test_expect_success 'reset with wildcard pathspec' '
588588
test_all_match git status --porcelain=v2
589589
'
590590

591+
# NEEDSWORK: although update-index executes without error on files outside
592+
# the sparse checkout definition, it does not actually add the file to the
593+
# index. This is also true when "--no-ignore-skip-worktree-entries" is
594+
# specified.
595+
test_expect_success 'update-index add outside sparse definition' '
596+
init_repos &&
597+
598+
write_script edit-contents <<-\EOF &&
599+
echo text >>$1
600+
EOF
601+
602+
run_on_sparse mkdir -p folder1 &&
603+
run_on_sparse cp ../initial-repo/folder1/a folder1/a &&
604+
605+
# Edit the file only in sparse checkouts so that, when checking the status
606+
# of the index, the unmodified full-checkout is compared to the "modified"
607+
# sparse checkouts.
608+
run_on_sparse ../edit-contents folder1/a &&
609+
610+
test_sparse_match git update-index --add folder1/a &&
611+
test_all_match git status --porcelain=v2 &&
612+
test_sparse_match git update-index --add --no-ignore-skip-worktree-entries folder1/a &&
613+
test_all_match git status --porcelain=v2
614+
'
615+
616+
test_expect_success 'update-index remove outside sparse definition' '
617+
init_repos &&
618+
619+
# When --remove is specified, files outside the sparse checkout definition
620+
# are considered "removed".
621+
rm -f full-checkout/folder1/a &&
622+
test_all_match git update-index --remove folder1/a &&
623+
test_all_match git status --porcelain=v2 &&
624+
625+
git reset --hard &&
626+
627+
# When --ignore-skip-worktree-entries is explicitly specified, a file
628+
# outside the sparse definition is not added to the index as "removed"
629+
# (thus matching the unmodified full-checkout).
630+
test_sparse_match git update-index --remove --ignore-skip-worktree-entries folder1/a &&
631+
test_all_match git status --porcelain=v2 &&
632+
633+
git reset --hard &&
634+
635+
# --force-remove supercedes --ignore-skip-worktree-entries and always
636+
# removes the file from the index.
637+
test_all_match git update-index --force-remove --ignore-skip-worktree-entries folder1/a &&
638+
test_all_match git status --porcelain=v2
639+
'
640+
641+
test_expect_success 'update-index folder add/remove' '
642+
init_repos &&
643+
644+
test_all_match test_must_fail git update-index --add --remove deep &&
645+
test_all_match test_must_fail git update-index --add --remove deep/ &&
646+
647+
# NEEDSWORK: attempting to update-index on an existing folder outside the
648+
# sparse checkout definition does not throw an error (as it does for folders
649+
# inside the definition, or in the full checkout). However, it is a no-op.
650+
test_sparse_match git update-index --add --remove folder1 &&
651+
test_sparse_match git update-index --add --remove folder1/ &&
652+
test_sparse_match git update-index --force-remove folder1/ &&
653+
test_all_match git status --porcelain=v2 &&
654+
655+
# New folders, even in sparse checkouts, throw an error on update-index
656+
run_on_all mkdir folder3 &&
657+
run_on_all cp a folder3/a &&
658+
run_on_all test_must_fail git update-index --add --remove folder3
659+
'
660+
661+
test_expect_success 'update-index with updated flags' '
662+
init_repos &&
663+
664+
# NEEDSWORK: updating flags runs inconsistently on directories, performing no
665+
# operation with warning text specifying the path being ignored if a trailing
666+
# slash is in the path, but throwing an error if there is no trailing slash.
667+
test_all_match test_must_fail git update-index --no-skip-worktree folder1 &&
668+
test_all_match git update-index --no-skip-worktree folder1/ &&
669+
test_all_match git status --porcelain=v2 &&
670+
671+
# Removing the skip-worktree bit from a file outside the sparse checkout
672+
# will cause the file to appear as unstaged and deleted.
673+
test_sparse_match git update-index --no-skip-worktree folder1/a &&
674+
rm -f full-checkout/folder1/a &&
675+
test_all_match git status --porcelain=v2
676+
'
677+
678+
test_expect_success 'update-index --again file outside sparse definition' '
679+
init_repos &&
680+
681+
write_script edit-contents <<-\EOF &&
682+
echo text >>$1
683+
EOF
684+
685+
# When a file is manually added and modified outside the checkout
686+
# definition, it will not be changed with `--again` because its changes are
687+
# not tracked in the index.
688+
run_on_sparse mkdir -p folder1 &&
689+
run_on_sparse ../edit-contents folder1/a &&
690+
test_sparse_match git update-index --again &&
691+
test_sparse_match git status --porcelain=v2 &&
692+
693+
# Update the sparse checkouts so that folder1/a is no longer skipped and
694+
# exists on-disk
695+
run_on_sparse cp ../initial-repo/folder1/a folder1/a &&
696+
test_sparse_match git update-index --no-skip-worktree folder1/a &&
697+
test_all_match git status --porcelain=v2 &&
698+
699+
# Stage change for commit
700+
run_on_all ../edit-contents folder1/a &&
701+
test_all_match git update-index folder1/a &&
702+
test_all_match git status --porcelain=v2 &&
703+
704+
# Modify the file
705+
run_on_all ../edit-contents folder1/a &&
706+
test_all_match git status --porcelain=v2 &&
707+
708+
# Run update-index --again, which re-stages the local changes
709+
test_all_match git update-index --again &&
710+
test_all_match git ls-files -s folder1/a &&
711+
test_all_match git status --porcelain=v2 &&
712+
713+
# Running update-index --again with staged changes after manually deleting
714+
# the file on disk will cause it to fail if --remove is not also specified
715+
run_on_all rm -f folder1/a &&
716+
test_all_match test_must_fail git update-index --again folder1 &&
717+
test_all_match git update-index --remove --again &&
718+
test_all_match git status --porcelain=v2
719+
'
720+
721+
test_expect_success 'update-index --cacheinfo' '
722+
init_repos &&
723+
724+
deep_a_oid=$(git -C full-checkout rev-parse update-deep:deep/a) &&
725+
folder2_oid=$(git -C full-checkout rev-parse update-folder2:folder2) &&
726+
folder1_a_oid=$(git -C full-checkout rev-parse update-folder1:folder1/a) &&
727+
728+
test_all_match git update-index --cacheinfo 100644 $deep_a_oid deep/a &&
729+
test_all_match git status --porcelain=v2 &&
730+
731+
# Cannot add sparse directory, even in sparse index case
732+
test_all_match test_must_fail git update-index --add --cacheinfo 040000 $folder2_oid folder2/ &&
733+
734+
# Sparse match only - because folder1/a is outside the sparse checkout
735+
# definition (and thus not on-disk), it will appear as "deleted" in
736+
# unstaged changes.
737+
test_all_match git update-index --add --cacheinfo 100644 $folder1_a_oid folder1/a &&
738+
test_sparse_match git status --porcelain=v2
739+
'
740+
591741
test_expect_success 'merge, cherry-pick, and rebase' '
592742
init_repos &&
593743

0 commit comments

Comments
 (0)