]> git.ipfire.org Git - thirdparty/git.git/blame - t/t7519-status-fsmonitor.sh
help: make sure local html page exists before calling external processes
[thirdparty/git.git] / t / t7519-status-fsmonitor.sh
CommitLineData
5c8cdcfd
BP
1#!/bin/sh
2
3test_description='git status with file system watcher'
4
5. ./test-lib.sh
6
5c8cdcfd
BP
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
11clean_repo () {
12 git reset --hard HEAD &&
13 git clean -fd
14}
15
16dirty_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
28write_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
8da2c576 35 if test "$1" != 2
5c8cdcfd
BP
36 then
37 echo "Unsupported core.fsmonitor hook version." >&2
38 exit 1
39 fi
8da2c576 40 printf "last_update_token\0"
5c8cdcfd
BP
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
53test_lazy_prereq UNTRACKED_CACHE '
54 { git update-index --test-untracked-cache; ret=$?; } &&
55 test $ret -ne 1
56'
57
58test_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*
f8fe49e5 76 trace2*
5c8cdcfd
BP
77 EOF
78'
79
80# test that the fsmonitor extension is off by default
81test_expect_success 'fsmonitor extension is off by default' '
f1ef0b02 82 test-tool dump-fsmonitor >actual &&
5c8cdcfd
BP
83 grep "^no fsmonitor" actual
84'
85
86# test that "update-index --fsmonitor" adds the fsmonitor extension
87test_expect_success 'update-index --fsmonitor" adds the fsmonitor extension' '
88 git update-index --fsmonitor &&
f1ef0b02 89 test-tool dump-fsmonitor >actual &&
5c8cdcfd
BP
90 grep "^fsmonitor last update" actual
91'
92
93# test that "update-index --no-fsmonitor" removes the fsmonitor extension
94test_expect_success 'update-index --no-fsmonitor" removes the fsmonitor extension' '
95 git update-index --no-fsmonitor &&
f1ef0b02 96 test-tool dump-fsmonitor >actual &&
5c8cdcfd
BP
97 grep "^no fsmonitor" actual
98'
99
100cat >expect <<EOF &&
101h dir1/modified
102H dir1/tracked
103h dir2/modified
104H dir2/tracked
105h modified
106H tracked
107EOF
108
109# test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit
110test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' '
679f2f9f 111 write_script .git/hooks/fsmonitor-test<<-\EOF &&
8da2c576 112 printf "last_update_token\0"
679f2f9f 113 EOF
5c8cdcfd
BP
114 git update-index --fsmonitor &&
115 git update-index --fsmonitor-valid dir1/modified &&
116 git update-index --fsmonitor-valid dir2/modified &&
117 git update-index --fsmonitor-valid modified &&
118 git ls-files -f >actual &&
119 test_cmp expect actual
120'
121
122cat >expect <<EOF &&
123H dir1/modified
124H dir1/tracked
125H dir2/modified
126H dir2/tracked
127H modified
128H tracked
129EOF
130
131# test that "update-index --no-fsmonitor-valid" clears the fsmonitor valid bit
132test_expect_success 'update-index --no-fsmonitor-valid" clears the fsmonitor valid bit' '
133 git update-index --no-fsmonitor-valid dir1/modified &&
134 git update-index --no-fsmonitor-valid dir2/modified &&
135 git update-index --no-fsmonitor-valid modified &&
136 git ls-files -f >actual &&
137 test_cmp expect actual
138'
139
140cat >expect <<EOF &&
141H dir1/modified
142H dir1/tracked
143H dir2/modified
144H dir2/tracked
145H modified
146H tracked
147EOF
148
149# test that all files returned by the script get flagged as invalid
150test_expect_success 'all files returned by integration script get flagged as invalid' '
151 write_integration_script &&
152 dirty_repo &&
153 git update-index --fsmonitor &&
154 git ls-files -f >actual &&
155 test_cmp expect actual
156'
157
158cat >expect <<EOF &&
159H dir1/modified
160h dir1/new
161H dir1/tracked
162H dir2/modified
163h dir2/new
164H dir2/tracked
165H modified
166h new
167H tracked
168EOF
169
170# test that newly added files are marked valid
171test_expect_success 'newly added files are marked valid' '
679f2f9f 172 write_script .git/hooks/fsmonitor-test<<-\EOF &&
8da2c576 173 printf "last_update_token\0"
679f2f9f 174 EOF
5c8cdcfd
BP
175 git add new &&
176 git add dir1/new &&
177 git add dir2/new &&
178 git ls-files -f >actual &&
179 test_cmp expect actual
180'
181
182cat >expect <<EOF &&
183H dir1/modified
184h dir1/new
185h dir1/tracked
186H dir2/modified
187h dir2/new
188h dir2/tracked
189H modified
190h new
191h tracked
192EOF
193
194# test that all unmodified files get marked valid
195test_expect_success 'all unmodified files get marked valid' '
196 # modified files result in update-index returning 1
197 test_must_fail git update-index --refresh --force-write-index &&
198 git ls-files -f >actual &&
199 test_cmp expect actual
200'
201
202cat >expect <<EOF &&
203H dir1/modified
204h dir1/tracked
205h dir2/modified
206h dir2/tracked
207h modified
208h tracked
209EOF
210
211# test that *only* files returned by the integration script get flagged as invalid
212test_expect_success '*only* files returned by the integration script get flagged as invalid' '
213 write_script .git/hooks/fsmonitor-test<<-\EOF &&
8da2c576 214 printf "last_update_token\0"
5c8cdcfd
BP
215 printf "dir1/modified\0"
216 EOF
217 clean_repo &&
218 git update-index --refresh --force-write-index &&
219 echo 1 >modified &&
220 echo 2 >dir1/modified &&
221 echo 3 >dir2/modified &&
222 test_must_fail git update-index --refresh --force-write-index &&
223 git ls-files -f >actual &&
224 test_cmp expect actual
225'
226
227# Ensure commands that call refresh_index() to move the index back in time
228# properly invalidate the fsmonitor cache
229test_expect_success 'refresh_index() invalidates fsmonitor cache' '
5c8cdcfd
BP
230 clean_repo &&
231 dirty_repo &&
679f2f9f 232 write_integration_script &&
5c8cdcfd 233 git add . &&
679f2f9f
US
234 write_script .git/hooks/fsmonitor-test<<-\EOF &&
235 EOF
5c8cdcfd
BP
236 git commit -m "to reset" &&
237 git reset HEAD~1 &&
238 git status >actual &&
239 git -c core.fsmonitor= status >expect &&
1108cea7 240 test_cmp expect actual
5c8cdcfd
BP
241'
242
243# test fsmonitor with and without preloadIndex
244preload_values="false true"
245for preload_val in $preload_values
246do
247 test_expect_success "setup preloadIndex to $preload_val" '
248 git config core.preloadIndex $preload_val &&
249 if test $preload_val = true
250 then
5765d97b 251 GIT_TEST_PRELOAD_INDEX=$preload_val; export GIT_TEST_PRELOAD_INDEX
5c8cdcfd 252 else
5765d97b 253 sane_unset GIT_TEST_PRELOAD_INDEX
5c8cdcfd
BP
254 fi
255 '
256
257 # test fsmonitor with and without the untracked cache (if available)
258 uc_values="false"
259 test_have_prereq UNTRACKED_CACHE && uc_values="false true"
260 for uc_val in $uc_values
261 do
262 test_expect_success "setup untracked cache to $uc_val" '
263 git config core.untrackedcache $uc_val
264 '
265
266 # Status is well tested elsewhere so we'll just ensure that the results are
267 # the same when using core.fsmonitor.
268 test_expect_success 'compare status with and without fsmonitor' '
269 write_integration_script &&
270 clean_repo &&
271 dirty_repo &&
272 git add new &&
273 git add dir1/new &&
274 git add dir2/new &&
275 git status >actual &&
276 git -c core.fsmonitor= status >expect &&
1108cea7 277 test_cmp expect actual
5c8cdcfd
BP
278 '
279
280 # Make sure it's actually skipping the check for modified and untracked
281 # (if enabled) files unless it is told about them.
282 test_expect_success "status doesn't detect unreported modifications" '
283 write_script .git/hooks/fsmonitor-test<<-\EOF &&
8da2c576 284 printf "last_update_token\0"
5c8cdcfd
BP
285 :>marker
286 EOF
287 clean_repo &&
288 git status &&
289 test_path_is_file marker &&
290 dirty_repo &&
291 rm -f marker &&
292 git status >actual &&
293 test_path_is_file marker &&
294 test_i18ngrep ! "Changes not staged for commit:" actual &&
295 if test $uc_val = true
296 then
297 test_i18ngrep ! "Untracked files:" actual
298 fi &&
299 if test $uc_val = false
300 then
301 test_i18ngrep "Untracked files:" actual
302 fi &&
303 rm -f marker
304 '
305 done
306done
307
7a40cf15 308# test that splitting the index doesn't interfere
3bd28eb2
AV
309test_expect_success 'splitting the index results in the same state' '
310 write_integration_script &&
311 dirty_repo &&
312 git update-index --fsmonitor &&
313 git ls-files -f >expect &&
f1ef0b02 314 test-tool dump-fsmonitor >&2 && echo &&
3bd28eb2 315 git update-index --fsmonitor --split-index &&
f1ef0b02 316 test-tool dump-fsmonitor >&2 && echo &&
3bd28eb2
AV
317 git ls-files -f >actual &&
318 test_cmp expect actual
319'
320
0cacebf0
NTND
321test_expect_success UNTRACKED_CACHE 'ignore .git changes when invalidating UNTR' '
322 test_create_repo dot-git &&
323 (
324 cd dot-git &&
325 mkdir -p .git/hooks &&
326 : >tracked &&
327 : >modified &&
328 mkdir dir1 &&
329 : >dir1/tracked &&
330 : >dir1/modified &&
331 mkdir dir2 &&
332 : >dir2/tracked &&
333 : >dir2/modified &&
334 write_integration_script &&
335 git config core.fsmonitor .git/hooks/fsmonitor-test &&
336 git update-index --untracked-cache &&
337 git update-index --fsmonitor &&
7f9dd879 338 GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace-before" \
0cacebf0 339 git status &&
cd780f0b 340 test-tool dump-untracked-cache >../before
0cacebf0
NTND
341 ) &&
342 cat >>dot-git/.git/hooks/fsmonitor-test <<-\EOF &&
343 printf ".git\0"
344 printf ".git/index\0"
345 printf "dir1/.git\0"
346 printf "dir1/.git/index\0"
347 EOF
348 (
349 cd dot-git &&
7f9dd879 350 GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace-after" \
0cacebf0 351 git status &&
cd780f0b 352 test-tool dump-untracked-cache >../after
0cacebf0 353 ) &&
7f9dd879
EN
354 grep "directory-invalidation" trace-before | cut -d"|" -f 9 >>before &&
355 grep "directory-invalidation" trace-after | cut -d"|" -f 9 >>after &&
0cacebf0
NTND
356 # UNTR extension unchanged, dir invalidation count unchanged
357 test_cmp before after
358'
359
398a3b08 360test_expect_success 'discard_index() also discards fsmonitor info' '
dc76852d
JS
361 test_config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-all" &&
362 test_might_fail git update-index --refresh &&
363 test-tool read-cache --print-and-refresh=tracked 2 >actual &&
364 printf "tracked is%s up to date\n" "" " not" >expect &&
365 test_cmp expect actual
366'
367
460782b7
WB
368# Test unstaging entries that:
369# - Are not flagged with CE_FSMONITOR_VALID
370# - Have a position in the index >= the number of entries present in the index
371# after unstaging.
372test_expect_success 'status succeeds after staging/unstaging' '
3444ec2e
WB
373 test_create_repo fsmonitor-stage-unstage &&
374 (
375 cd fsmonitor-stage-unstage &&
376 test_commit initial &&
377 git update-index --fsmonitor &&
378 removed=$(test_seq 1 100 | sed "s/^/z/") &&
379 touch $removed &&
380 git add $removed &&
381 git config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-env" &&
382 FSMONITOR_LIST="$removed" git restore -S $removed &&
383 FSMONITOR_LIST="$removed" git status
384 )
385'
386
f8fe49e5
DS
387# Usage:
388# check_sparse_index_behavior [!]
389# If "!" is supplied, then we verify that we do not call ensure_full_index
390# during a call to 'git status'. Otherwise, we verify that we _do_ call it.
391check_sparse_index_behavior () {
392 git status --porcelain=v2 >expect &&
393 git sparse-checkout init --cone --sparse-index &&
394 git sparse-checkout set dir1 dir2 &&
395 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
396 git status --porcelain=v2 >actual &&
397 test_region $1 index ensure_full_index trace2.txt &&
398 test_region fsm_hook query trace2.txt &&
399 test_cmp expect actual &&
400 rm trace2.txt &&
401 git sparse-checkout disable
402}
403
404test_expect_success 'status succeeds with sparse index' '
405 git reset --hard &&
406
407 test_config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-all" &&
408 check_sparse_index_behavior ! &&
409
410 write_script .git/hooks/fsmonitor-test<<-\EOF &&
411 printf "last_update_token\0"
412 EOF
413 git config core.fsmonitor .git/hooks/fsmonitor-test &&
414 check_sparse_index_behavior ! &&
415
416 write_script .git/hooks/fsmonitor-test<<-\EOF &&
417 printf "last_update_token\0"
418 printf "dir1/modified\0"
419 EOF
420 check_sparse_index_behavior ! &&
421
422 cp -r dir1 dir1a &&
423 git add dir1a &&
424 git commit -m "add dir1a" &&
425
426 # This one modifies outside the sparse-checkout definition
427 # and hence we expect to expand the sparse-index.
428 write_script .git/hooks/fsmonitor-test<<-\EOF &&
429 printf "last_update_token\0"
430 printf "dir1a/modified\0"
431 EOF
432 check_sparse_index_behavior
433'
434
5c8cdcfd 435test_done