You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
386 lines
9.8 KiB
386 lines
9.8 KiB
#!/bin/sh |
|
|
|
test_description='git status with file system watcher' |
|
|
|
. ./test-lib.sh |
|
|
|
# Note, after "git reset --hard HEAD" no extensions exist other than 'TREE' |
|
# "git update-index --fsmonitor" can be used to get the extension written |
|
# before testing the results. |
|
|
|
clean_repo () { |
|
git reset --hard HEAD && |
|
git clean -fd |
|
} |
|
|
|
dirty_repo () { |
|
: >untracked && |
|
: >dir1/untracked && |
|
: >dir2/untracked && |
|
echo 1 >modified && |
|
echo 2 >dir1/modified && |
|
echo 3 >dir2/modified && |
|
echo 4 >new && |
|
echo 5 >dir1/new && |
|
echo 6 >dir2/new |
|
} |
|
|
|
write_integration_script () { |
|
write_script .git/hooks/fsmonitor-test<<-\EOF |
|
if test "$#" -ne 2 |
|
then |
|
echo "$0: exactly 2 arguments expected" |
|
exit 2 |
|
fi |
|
if test "$1" != 2 |
|
then |
|
echo "Unsupported core.fsmonitor hook version." >&2 |
|
exit 1 |
|
fi |
|
printf "last_update_token\0" |
|
printf "untracked\0" |
|
printf "dir1/untracked\0" |
|
printf "dir2/untracked\0" |
|
printf "modified\0" |
|
printf "dir1/modified\0" |
|
printf "dir2/modified\0" |
|
printf "new\0" |
|
printf "dir1/new\0" |
|
printf "dir2/new\0" |
|
EOF |
|
} |
|
|
|
test_lazy_prereq UNTRACKED_CACHE ' |
|
{ git update-index --test-untracked-cache; ret=$?; } && |
|
test $ret -ne 1 |
|
' |
|
|
|
test_expect_success 'setup' ' |
|
mkdir -p .git/hooks && |
|
: >tracked && |
|
: >modified && |
|
mkdir dir1 && |
|
: >dir1/tracked && |
|
: >dir1/modified && |
|
mkdir dir2 && |
|
: >dir2/tracked && |
|
: >dir2/modified && |
|
git -c core.fsmonitor= add . && |
|
git -c core.fsmonitor= commit -m initial && |
|
git config core.fsmonitor .git/hooks/fsmonitor-test && |
|
cat >.gitignore <<-\EOF |
|
.gitignore |
|
expect* |
|
actual* |
|
marker* |
|
EOF |
|
' |
|
|
|
# test that the fsmonitor extension is off by default |
|
test_expect_success 'fsmonitor extension is off by default' ' |
|
test-tool dump-fsmonitor >actual && |
|
grep "^no fsmonitor" actual |
|
' |
|
|
|
# test that "update-index --fsmonitor" adds the fsmonitor extension |
|
test_expect_success 'update-index --fsmonitor" adds the fsmonitor extension' ' |
|
git update-index --fsmonitor && |
|
test-tool dump-fsmonitor >actual && |
|
grep "^fsmonitor last update" actual |
|
' |
|
|
|
# test that "update-index --no-fsmonitor" removes the fsmonitor extension |
|
test_expect_success 'update-index --no-fsmonitor" removes the fsmonitor extension' ' |
|
git update-index --no-fsmonitor && |
|
test-tool dump-fsmonitor >actual && |
|
grep "^no fsmonitor" actual |
|
' |
|
|
|
cat >expect <<EOF && |
|
h dir1/modified |
|
H dir1/tracked |
|
h dir2/modified |
|
H dir2/tracked |
|
h modified |
|
H tracked |
|
EOF |
|
|
|
# test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit |
|
test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' ' |
|
write_script .git/hooks/fsmonitor-test<<-\EOF && |
|
printf "last_update_token\0" |
|
EOF |
|
git update-index --fsmonitor && |
|
git update-index --fsmonitor-valid dir1/modified && |
|
git update-index --fsmonitor-valid dir2/modified && |
|
git update-index --fsmonitor-valid modified && |
|
git ls-files -f >actual && |
|
test_cmp expect actual |
|
' |
|
|
|
cat >expect <<EOF && |
|
H dir1/modified |
|
H dir1/tracked |
|
H dir2/modified |
|
H dir2/tracked |
|
H modified |
|
H tracked |
|
EOF |
|
|
|
# test that "update-index --no-fsmonitor-valid" clears the fsmonitor valid bit |
|
test_expect_success 'update-index --no-fsmonitor-valid" clears the fsmonitor valid bit' ' |
|
git update-index --no-fsmonitor-valid dir1/modified && |
|
git update-index --no-fsmonitor-valid dir2/modified && |
|
git update-index --no-fsmonitor-valid modified && |
|
git ls-files -f >actual && |
|
test_cmp expect actual |
|
' |
|
|
|
cat >expect <<EOF && |
|
H dir1/modified |
|
H dir1/tracked |
|
H dir2/modified |
|
H dir2/tracked |
|
H modified |
|
H tracked |
|
EOF |
|
|
|
# test that all files returned by the script get flagged as invalid |
|
test_expect_success 'all files returned by integration script get flagged as invalid' ' |
|
write_integration_script && |
|
dirty_repo && |
|
git update-index --fsmonitor && |
|
git ls-files -f >actual && |
|
test_cmp expect actual |
|
' |
|
|
|
cat >expect <<EOF && |
|
H dir1/modified |
|
h dir1/new |
|
H dir1/tracked |
|
H dir2/modified |
|
h dir2/new |
|
H dir2/tracked |
|
H modified |
|
h new |
|
H tracked |
|
EOF |
|
|
|
# test that newly added files are marked valid |
|
test_expect_success 'newly added files are marked valid' ' |
|
write_script .git/hooks/fsmonitor-test<<-\EOF && |
|
printf "last_update_token\0" |
|
EOF |
|
git add new && |
|
git add dir1/new && |
|
git add dir2/new && |
|
git ls-files -f >actual && |
|
test_cmp expect actual |
|
' |
|
|
|
cat >expect <<EOF && |
|
H dir1/modified |
|
h dir1/new |
|
h dir1/tracked |
|
H dir2/modified |
|
h dir2/new |
|
h dir2/tracked |
|
H modified |
|
h new |
|
h tracked |
|
EOF |
|
|
|
# test that all unmodified files get marked valid |
|
test_expect_success 'all unmodified files get marked valid' ' |
|
# modified files result in update-index returning 1 |
|
test_must_fail git update-index --refresh --force-write-index && |
|
git ls-files -f >actual && |
|
test_cmp expect actual |
|
' |
|
|
|
cat >expect <<EOF && |
|
H dir1/modified |
|
h dir1/tracked |
|
h dir2/modified |
|
h dir2/tracked |
|
h modified |
|
h tracked |
|
EOF |
|
|
|
# test that *only* files returned by the integration script get flagged as invalid |
|
test_expect_success '*only* files returned by the integration script get flagged as invalid' ' |
|
write_script .git/hooks/fsmonitor-test<<-\EOF && |
|
printf "last_update_token\0" |
|
printf "dir1/modified\0" |
|
EOF |
|
clean_repo && |
|
git update-index --refresh --force-write-index && |
|
echo 1 >modified && |
|
echo 2 >dir1/modified && |
|
echo 3 >dir2/modified && |
|
test_must_fail git update-index --refresh --force-write-index && |
|
git ls-files -f >actual && |
|
test_cmp expect actual |
|
' |
|
|
|
# Ensure commands that call refresh_index() to move the index back in time |
|
# properly invalidate the fsmonitor cache |
|
test_expect_success 'refresh_index() invalidates fsmonitor cache' ' |
|
clean_repo && |
|
dirty_repo && |
|
write_integration_script && |
|
git add . && |
|
write_script .git/hooks/fsmonitor-test<<-\EOF && |
|
EOF |
|
git commit -m "to reset" && |
|
git reset HEAD~1 && |
|
git status >actual && |
|
git -c core.fsmonitor= status >expect && |
|
test_i18ncmp expect actual |
|
' |
|
|
|
# test fsmonitor with and without preloadIndex |
|
preload_values="false true" |
|
for preload_val in $preload_values |
|
do |
|
test_expect_success "setup preloadIndex to $preload_val" ' |
|
git config core.preloadIndex $preload_val && |
|
if test $preload_val = true |
|
then |
|
GIT_TEST_PRELOAD_INDEX=$preload_val; export GIT_TEST_PRELOAD_INDEX |
|
else |
|
sane_unset GIT_TEST_PRELOAD_INDEX |
|
fi |
|
' |
|
|
|
# test fsmonitor with and without the untracked cache (if available) |
|
uc_values="false" |
|
test_have_prereq UNTRACKED_CACHE && uc_values="false true" |
|
for uc_val in $uc_values |
|
do |
|
test_expect_success "setup untracked cache to $uc_val" ' |
|
git config core.untrackedcache $uc_val |
|
' |
|
|
|
# Status is well tested elsewhere so we'll just ensure that the results are |
|
# the same when using core.fsmonitor. |
|
test_expect_success 'compare status with and without fsmonitor' ' |
|
write_integration_script && |
|
clean_repo && |
|
dirty_repo && |
|
git add new && |
|
git add dir1/new && |
|
git add dir2/new && |
|
git status >actual && |
|
git -c core.fsmonitor= status >expect && |
|
test_i18ncmp expect actual |
|
' |
|
|
|
# Make sure it's actually skipping the check for modified and untracked |
|
# (if enabled) files unless it is told about them. |
|
test_expect_success "status doesn't detect unreported modifications" ' |
|
write_script .git/hooks/fsmonitor-test<<-\EOF && |
|
printf "last_update_token\0" |
|
:>marker |
|
EOF |
|
clean_repo && |
|
git status && |
|
test_path_is_file marker && |
|
dirty_repo && |
|
rm -f marker && |
|
git status >actual && |
|
test_path_is_file marker && |
|
test_i18ngrep ! "Changes not staged for commit:" actual && |
|
if test $uc_val = true |
|
then |
|
test_i18ngrep ! "Untracked files:" actual |
|
fi && |
|
if test $uc_val = false |
|
then |
|
test_i18ngrep "Untracked files:" actual |
|
fi && |
|
rm -f marker |
|
' |
|
done |
|
done |
|
|
|
# test that splitting the index doesn't interfere |
|
test_expect_success 'splitting the index results in the same state' ' |
|
write_integration_script && |
|
dirty_repo && |
|
git update-index --fsmonitor && |
|
git ls-files -f >expect && |
|
test-tool dump-fsmonitor >&2 && echo && |
|
git update-index --fsmonitor --split-index && |
|
test-tool dump-fsmonitor >&2 && echo && |
|
git ls-files -f >actual && |
|
test_cmp expect actual |
|
' |
|
|
|
test_expect_success UNTRACKED_CACHE 'ignore .git changes when invalidating UNTR' ' |
|
test_create_repo dot-git && |
|
( |
|
cd dot-git && |
|
mkdir -p .git/hooks && |
|
: >tracked && |
|
: >modified && |
|
mkdir dir1 && |
|
: >dir1/tracked && |
|
: >dir1/modified && |
|
mkdir dir2 && |
|
: >dir2/tracked && |
|
: >dir2/modified && |
|
write_integration_script && |
|
git config core.fsmonitor .git/hooks/fsmonitor-test && |
|
git update-index --untracked-cache && |
|
git update-index --fsmonitor && |
|
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace-before" \ |
|
git status && |
|
test-tool dump-untracked-cache >../before |
|
) && |
|
cat >>dot-git/.git/hooks/fsmonitor-test <<-\EOF && |
|
printf ".git\0" |
|
printf ".git/index\0" |
|
printf "dir1/.git\0" |
|
printf "dir1/.git/index\0" |
|
EOF |
|
( |
|
cd dot-git && |
|
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace-after" \ |
|
git status && |
|
test-tool dump-untracked-cache >../after |
|
) && |
|
grep "directory invalidation" trace-before >>before && |
|
grep "directory invalidation" trace-after >>after && |
|
# UNTR extension unchanged, dir invalidation count unchanged |
|
test_cmp before after |
|
' |
|
|
|
test_expect_success 'discard_index() also discards fsmonitor info' ' |
|
test_config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-all" && |
|
test_might_fail git update-index --refresh && |
|
test-tool read-cache --print-and-refresh=tracked 2 >actual && |
|
printf "tracked is%s up to date\n" "" " not" >expect && |
|
test_cmp expect actual |
|
' |
|
|
|
# Test unstaging entries that: |
|
# - Are not flagged with CE_FSMONITOR_VALID |
|
# - Have a position in the index >= the number of entries present in the index |
|
# after unstaging. |
|
test_expect_success 'status succeeds after staging/unstaging' ' |
|
test_create_repo fsmonitor-stage-unstage && |
|
( |
|
cd fsmonitor-stage-unstage && |
|
test_commit initial && |
|
git update-index --fsmonitor && |
|
removed=$(test_seq 1 100 | sed "s/^/z/") && |
|
touch $removed && |
|
git add $removed && |
|
git config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-env" && |
|
FSMONITOR_LIST="$removed" git restore -S $removed && |
|
FSMONITOR_LIST="$removed" git status |
|
) |
|
' |
|
|
|
test_done
|
|
|