Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='git status with file system watcher' |
| 4 | |
| 5 | . ./test-lib.sh |
| 6 | |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 7 | # Note, after "git reset --hard HEAD" no extensions exist other than 'TREE' |
| 8 | # "git update-index --fsmonitor" can be used to get the extension written |
| 9 | # before testing the results. |
| 10 | |
| 11 | clean_repo () { |
| 12 | git reset --hard HEAD && |
| 13 | git clean -fd |
| 14 | } |
| 15 | |
| 16 | dirty_repo () { |
| 17 | : >untracked && |
| 18 | : >dir1/untracked && |
| 19 | : >dir2/untracked && |
| 20 | echo 1 >modified && |
| 21 | echo 2 >dir1/modified && |
| 22 | echo 3 >dir2/modified && |
| 23 | echo 4 >new && |
| 24 | echo 5 >dir1/new && |
| 25 | echo 6 >dir2/new |
| 26 | } |
| 27 | |
| 28 | write_integration_script () { |
| 29 | write_script .git/hooks/fsmonitor-test<<-\EOF |
| 30 | if test "$#" -ne 2 |
| 31 | then |
| 32 | echo "$0: exactly 2 arguments expected" |
| 33 | exit 2 |
| 34 | fi |
Kevin Willford | 8da2c57 | 2020-01-07 19:04:29 +0000 | [diff] [blame] | 35 | if test "$1" != 2 |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 36 | then |
| 37 | echo "Unsupported core.fsmonitor hook version." >&2 |
| 38 | exit 1 |
| 39 | fi |
Kevin Willford | 8da2c57 | 2020-01-07 19:04:29 +0000 | [diff] [blame] | 40 | printf "last_update_token\0" |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 41 | printf "untracked\0" |
| 42 | printf "dir1/untracked\0" |
| 43 | printf "dir2/untracked\0" |
| 44 | printf "modified\0" |
| 45 | printf "dir1/modified\0" |
| 46 | printf "dir2/modified\0" |
| 47 | printf "new\0" |
| 48 | printf "dir1/new\0" |
| 49 | printf "dir2/new\0" |
| 50 | EOF |
| 51 | } |
| 52 | |
| 53 | test_lazy_prereq UNTRACKED_CACHE ' |
| 54 | { git update-index --test-untracked-cache; ret=$?; } && |
| 55 | test $ret -ne 1 |
| 56 | ' |
| 57 | |
| 58 | test_expect_success 'setup' ' |
| 59 | mkdir -p .git/hooks && |
| 60 | : >tracked && |
| 61 | : >modified && |
| 62 | mkdir dir1 && |
| 63 | : >dir1/tracked && |
| 64 | : >dir1/modified && |
| 65 | mkdir dir2 && |
| 66 | : >dir2/tracked && |
| 67 | : >dir2/modified && |
| 68 | git -c core.fsmonitor= add . && |
| 69 | git -c core.fsmonitor= commit -m initial && |
| 70 | git config core.fsmonitor .git/hooks/fsmonitor-test && |
| 71 | cat >.gitignore <<-\EOF |
| 72 | .gitignore |
| 73 | expect* |
| 74 | actual* |
| 75 | marker* |
| 76 | EOF |
| 77 | ' |
| 78 | |
| 79 | # test that the fsmonitor extension is off by default |
| 80 | test_expect_success 'fsmonitor extension is off by default' ' |
Nguyễn Thái Ngọc Duy | f1ef0b0 | 2018-09-09 19:36:30 +0200 | [diff] [blame] | 81 | test-tool dump-fsmonitor >actual && |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 82 | grep "^no fsmonitor" actual |
| 83 | ' |
| 84 | |
| 85 | # test that "update-index --fsmonitor" adds the fsmonitor extension |
| 86 | test_expect_success 'update-index --fsmonitor" adds the fsmonitor extension' ' |
| 87 | git update-index --fsmonitor && |
Nguyễn Thái Ngọc Duy | f1ef0b0 | 2018-09-09 19:36:30 +0200 | [diff] [blame] | 88 | test-tool dump-fsmonitor >actual && |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 89 | grep "^fsmonitor last update" actual |
| 90 | ' |
| 91 | |
| 92 | # test that "update-index --no-fsmonitor" removes the fsmonitor extension |
| 93 | test_expect_success 'update-index --no-fsmonitor" removes the fsmonitor extension' ' |
| 94 | git update-index --no-fsmonitor && |
Nguyễn Thái Ngọc Duy | f1ef0b0 | 2018-09-09 19:36:30 +0200 | [diff] [blame] | 95 | test-tool dump-fsmonitor >actual && |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 96 | grep "^no fsmonitor" actual |
| 97 | ' |
| 98 | |
| 99 | cat >expect <<EOF && |
| 100 | h dir1/modified |
| 101 | H dir1/tracked |
| 102 | h dir2/modified |
| 103 | H dir2/tracked |
| 104 | h modified |
| 105 | H tracked |
| 106 | EOF |
| 107 | |
| 108 | # test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit |
| 109 | test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' ' |
Utsav Shah | 679f2f9 | 2019-11-20 08:32:17 +0000 | [diff] [blame] | 110 | write_script .git/hooks/fsmonitor-test<<-\EOF && |
Kevin Willford | 8da2c57 | 2020-01-07 19:04:29 +0000 | [diff] [blame] | 111 | printf "last_update_token\0" |
Utsav Shah | 679f2f9 | 2019-11-20 08:32:17 +0000 | [diff] [blame] | 112 | EOF |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 113 | git update-index --fsmonitor && |
| 114 | git update-index --fsmonitor-valid dir1/modified && |
| 115 | git update-index --fsmonitor-valid dir2/modified && |
| 116 | git update-index --fsmonitor-valid modified && |
| 117 | git ls-files -f >actual && |
| 118 | test_cmp expect actual |
| 119 | ' |
| 120 | |
| 121 | cat >expect <<EOF && |
| 122 | H dir1/modified |
| 123 | H dir1/tracked |
| 124 | H dir2/modified |
| 125 | H dir2/tracked |
| 126 | H modified |
| 127 | H tracked |
| 128 | EOF |
| 129 | |
| 130 | # test that "update-index --no-fsmonitor-valid" clears the fsmonitor valid bit |
| 131 | test_expect_success 'update-index --no-fsmonitor-valid" clears the fsmonitor valid bit' ' |
| 132 | git update-index --no-fsmonitor-valid dir1/modified && |
| 133 | git update-index --no-fsmonitor-valid dir2/modified && |
| 134 | git update-index --no-fsmonitor-valid modified && |
| 135 | git ls-files -f >actual && |
| 136 | test_cmp expect actual |
| 137 | ' |
| 138 | |
| 139 | cat >expect <<EOF && |
| 140 | H dir1/modified |
| 141 | H dir1/tracked |
| 142 | H dir2/modified |
| 143 | H dir2/tracked |
| 144 | H modified |
| 145 | H tracked |
| 146 | EOF |
| 147 | |
| 148 | # test that all files returned by the script get flagged as invalid |
| 149 | test_expect_success 'all files returned by integration script get flagged as invalid' ' |
| 150 | write_integration_script && |
| 151 | dirty_repo && |
| 152 | git update-index --fsmonitor && |
| 153 | git ls-files -f >actual && |
| 154 | test_cmp expect actual |
| 155 | ' |
| 156 | |
| 157 | cat >expect <<EOF && |
| 158 | H dir1/modified |
| 159 | h dir1/new |
| 160 | H dir1/tracked |
| 161 | H dir2/modified |
| 162 | h dir2/new |
| 163 | H dir2/tracked |
| 164 | H modified |
| 165 | h new |
| 166 | H tracked |
| 167 | EOF |
| 168 | |
| 169 | # test that newly added files are marked valid |
| 170 | test_expect_success 'newly added files are marked valid' ' |
Utsav Shah | 679f2f9 | 2019-11-20 08:32:17 +0000 | [diff] [blame] | 171 | write_script .git/hooks/fsmonitor-test<<-\EOF && |
Kevin Willford | 8da2c57 | 2020-01-07 19:04:29 +0000 | [diff] [blame] | 172 | printf "last_update_token\0" |
Utsav Shah | 679f2f9 | 2019-11-20 08:32:17 +0000 | [diff] [blame] | 173 | EOF |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 174 | git add new && |
| 175 | git add dir1/new && |
| 176 | git add dir2/new && |
| 177 | git ls-files -f >actual && |
| 178 | test_cmp expect actual |
| 179 | ' |
| 180 | |
| 181 | cat >expect <<EOF && |
| 182 | H dir1/modified |
| 183 | h dir1/new |
| 184 | h dir1/tracked |
| 185 | H dir2/modified |
| 186 | h dir2/new |
| 187 | h dir2/tracked |
| 188 | H modified |
| 189 | h new |
| 190 | h tracked |
| 191 | EOF |
| 192 | |
| 193 | # test that all unmodified files get marked valid |
| 194 | test_expect_success 'all unmodified files get marked valid' ' |
| 195 | # modified files result in update-index returning 1 |
| 196 | test_must_fail git update-index --refresh --force-write-index && |
| 197 | git ls-files -f >actual && |
| 198 | test_cmp expect actual |
| 199 | ' |
| 200 | |
| 201 | cat >expect <<EOF && |
| 202 | H dir1/modified |
| 203 | h dir1/tracked |
| 204 | h dir2/modified |
| 205 | h dir2/tracked |
| 206 | h modified |
| 207 | h tracked |
| 208 | EOF |
| 209 | |
| 210 | # test that *only* files returned by the integration script get flagged as invalid |
| 211 | test_expect_success '*only* files returned by the integration script get flagged as invalid' ' |
| 212 | write_script .git/hooks/fsmonitor-test<<-\EOF && |
Kevin Willford | 8da2c57 | 2020-01-07 19:04:29 +0000 | [diff] [blame] | 213 | printf "last_update_token\0" |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 214 | printf "dir1/modified\0" |
| 215 | EOF |
| 216 | clean_repo && |
| 217 | git update-index --refresh --force-write-index && |
| 218 | echo 1 >modified && |
| 219 | echo 2 >dir1/modified && |
| 220 | echo 3 >dir2/modified && |
| 221 | test_must_fail git update-index --refresh --force-write-index && |
| 222 | git ls-files -f >actual && |
| 223 | test_cmp expect actual |
| 224 | ' |
| 225 | |
| 226 | # Ensure commands that call refresh_index() to move the index back in time |
| 227 | # properly invalidate the fsmonitor cache |
| 228 | test_expect_success 'refresh_index() invalidates fsmonitor cache' ' |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 229 | clean_repo && |
| 230 | dirty_repo && |
Utsav Shah | 679f2f9 | 2019-11-20 08:32:17 +0000 | [diff] [blame] | 231 | write_integration_script && |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 232 | git add . && |
Utsav Shah | 679f2f9 | 2019-11-20 08:32:17 +0000 | [diff] [blame] | 233 | write_script .git/hooks/fsmonitor-test<<-\EOF && |
| 234 | EOF |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 235 | git commit -m "to reset" && |
| 236 | git reset HEAD~1 && |
| 237 | git status >actual && |
| 238 | git -c core.fsmonitor= status >expect && |
| 239 | test_i18ncmp expect actual |
| 240 | ' |
| 241 | |
| 242 | # test fsmonitor with and without preloadIndex |
| 243 | preload_values="false true" |
| 244 | for preload_val in $preload_values |
| 245 | do |
| 246 | test_expect_success "setup preloadIndex to $preload_val" ' |
| 247 | git config core.preloadIndex $preload_val && |
| 248 | if test $preload_val = true |
| 249 | then |
Ben Peart | 5765d97 | 2018-09-18 23:29:37 +0000 | [diff] [blame] | 250 | GIT_TEST_PRELOAD_INDEX=$preload_val; export GIT_TEST_PRELOAD_INDEX |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 251 | else |
Ben Peart | 5765d97 | 2018-09-18 23:29:37 +0000 | [diff] [blame] | 252 | sane_unset GIT_TEST_PRELOAD_INDEX |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 253 | fi |
| 254 | ' |
| 255 | |
| 256 | # test fsmonitor with and without the untracked cache (if available) |
| 257 | uc_values="false" |
| 258 | test_have_prereq UNTRACKED_CACHE && uc_values="false true" |
| 259 | for uc_val in $uc_values |
| 260 | do |
| 261 | test_expect_success "setup untracked cache to $uc_val" ' |
| 262 | git config core.untrackedcache $uc_val |
| 263 | ' |
| 264 | |
| 265 | # Status is well tested elsewhere so we'll just ensure that the results are |
| 266 | # the same when using core.fsmonitor. |
| 267 | test_expect_success 'compare status with and without fsmonitor' ' |
| 268 | write_integration_script && |
| 269 | clean_repo && |
| 270 | dirty_repo && |
| 271 | git add new && |
| 272 | git add dir1/new && |
| 273 | git add dir2/new && |
| 274 | git status >actual && |
| 275 | git -c core.fsmonitor= status >expect && |
| 276 | test_i18ncmp expect actual |
| 277 | ' |
| 278 | |
| 279 | # Make sure it's actually skipping the check for modified and untracked |
| 280 | # (if enabled) files unless it is told about them. |
| 281 | test_expect_success "status doesn't detect unreported modifications" ' |
| 282 | write_script .git/hooks/fsmonitor-test<<-\EOF && |
Kevin Willford | 8da2c57 | 2020-01-07 19:04:29 +0000 | [diff] [blame] | 283 | printf "last_update_token\0" |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 284 | :>marker |
| 285 | EOF |
| 286 | clean_repo && |
| 287 | git status && |
| 288 | test_path_is_file marker && |
| 289 | dirty_repo && |
| 290 | rm -f marker && |
| 291 | git status >actual && |
| 292 | test_path_is_file marker && |
| 293 | test_i18ngrep ! "Changes not staged for commit:" actual && |
| 294 | if test $uc_val = true |
| 295 | then |
| 296 | test_i18ngrep ! "Untracked files:" actual |
| 297 | fi && |
| 298 | if test $uc_val = false |
| 299 | then |
| 300 | test_i18ngrep "Untracked files:" actual |
| 301 | fi && |
| 302 | rm -f marker |
| 303 | ' |
| 304 | done |
| 305 | done |
| 306 | |
Elijah Newren | 7a40cf1 | 2019-11-05 17:07:24 +0000 | [diff] [blame] | 307 | # test that splitting the index doesn't interfere |
Alex Vandiver | 3bd28eb | 2017-11-09 11:58:10 -0800 | [diff] [blame] | 308 | test_expect_success 'splitting the index results in the same state' ' |
| 309 | write_integration_script && |
| 310 | dirty_repo && |
| 311 | git update-index --fsmonitor && |
| 312 | git ls-files -f >expect && |
Nguyễn Thái Ngọc Duy | f1ef0b0 | 2018-09-09 19:36:30 +0200 | [diff] [blame] | 313 | test-tool dump-fsmonitor >&2 && echo && |
Alex Vandiver | 3bd28eb | 2017-11-09 11:58:10 -0800 | [diff] [blame] | 314 | git update-index --fsmonitor --split-index && |
Nguyễn Thái Ngọc Duy | f1ef0b0 | 2018-09-09 19:36:30 +0200 | [diff] [blame] | 315 | test-tool dump-fsmonitor >&2 && echo && |
Alex Vandiver | 3bd28eb | 2017-11-09 11:58:10 -0800 | [diff] [blame] | 316 | git ls-files -f >actual && |
| 317 | test_cmp expect actual |
| 318 | ' |
| 319 | |
Nguyễn Thái Ngọc Duy | 0cacebf | 2018-02-07 16:21:40 +0700 | [diff] [blame] | 320 | test_expect_success UNTRACKED_CACHE 'ignore .git changes when invalidating UNTR' ' |
| 321 | test_create_repo dot-git && |
| 322 | ( |
| 323 | cd dot-git && |
| 324 | mkdir -p .git/hooks && |
| 325 | : >tracked && |
| 326 | : >modified && |
| 327 | mkdir dir1 && |
| 328 | : >dir1/tracked && |
| 329 | : >dir1/modified && |
| 330 | mkdir dir2 && |
| 331 | : >dir2/tracked && |
| 332 | : >dir2/modified && |
| 333 | write_integration_script && |
| 334 | git config core.fsmonitor .git/hooks/fsmonitor-test && |
| 335 | git update-index --untracked-cache && |
| 336 | git update-index --fsmonitor && |
| 337 | GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace-before" \ |
| 338 | git status && |
Nguyễn Thái Ngọc Duy | cd780f0 | 2018-09-09 19:36:27 +0200 | [diff] [blame] | 339 | test-tool dump-untracked-cache >../before |
Nguyễn Thái Ngọc Duy | 0cacebf | 2018-02-07 16:21:40 +0700 | [diff] [blame] | 340 | ) && |
| 341 | cat >>dot-git/.git/hooks/fsmonitor-test <<-\EOF && |
| 342 | printf ".git\0" |
| 343 | printf ".git/index\0" |
| 344 | printf "dir1/.git\0" |
| 345 | printf "dir1/.git/index\0" |
| 346 | EOF |
| 347 | ( |
| 348 | cd dot-git && |
| 349 | GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace-after" \ |
| 350 | git status && |
Nguyễn Thái Ngọc Duy | cd780f0 | 2018-09-09 19:36:27 +0200 | [diff] [blame] | 351 | test-tool dump-untracked-cache >../after |
Nguyễn Thái Ngọc Duy | 0cacebf | 2018-02-07 16:21:40 +0700 | [diff] [blame] | 352 | ) && |
| 353 | grep "directory invalidation" trace-before >>before && |
| 354 | grep "directory invalidation" trace-after >>after && |
| 355 | # UNTR extension unchanged, dir invalidation count unchanged |
| 356 | test_cmp before after |
| 357 | ' |
| 358 | |
Johannes Schindelin | 398a3b0 | 2019-05-07 13:10:21 +0200 | [diff] [blame] | 359 | test_expect_success 'discard_index() also discards fsmonitor info' ' |
Johannes Schindelin | dc76852 | 2019-05-07 13:10:20 +0200 | [diff] [blame] | 360 | test_config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-all" && |
| 361 | test_might_fail git update-index --refresh && |
| 362 | test-tool read-cache --print-and-refresh=tracked 2 >actual && |
| 363 | printf "tracked is%s up to date\n" "" " not" >expect && |
| 364 | test_cmp expect actual |
| 365 | ' |
| 366 | |
William Baker | 460782b | 2019-10-16 19:35:47 +0000 | [diff] [blame] | 367 | # Test unstaging entries that: |
| 368 | # - Are not flagged with CE_FSMONITOR_VALID |
| 369 | # - Have a position in the index >= the number of entries present in the index |
| 370 | # after unstaging. |
| 371 | test_expect_success 'status succeeds after staging/unstaging' ' |
William Baker | 3444ec2 | 2019-10-11 13:11:23 -0700 | [diff] [blame] | 372 | test_create_repo fsmonitor-stage-unstage && |
| 373 | ( |
| 374 | cd fsmonitor-stage-unstage && |
| 375 | test_commit initial && |
| 376 | git update-index --fsmonitor && |
| 377 | removed=$(test_seq 1 100 | sed "s/^/z/") && |
| 378 | touch $removed && |
| 379 | git add $removed && |
| 380 | git config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-env" && |
| 381 | FSMONITOR_LIST="$removed" git restore -S $removed && |
| 382 | FSMONITOR_LIST="$removed" git status |
| 383 | ) |
| 384 | ' |
| 385 | |
Ben Peart | 5c8cdcf | 2017-09-22 12:35:46 -0400 | [diff] [blame] | 386 | test_done |