1
+#!/bin/sh
2
+
3
+test_description='git status with file system watcher'
4
+
5
+. ./test-lib.sh
6
+
7
+#
8
+# To run the entire git test suite using fsmonitor:
9
+#
10
+# copy t/t7519/fsmonitor-all to a location in your path and then set
11
+# GIT_FSMONITOR_TEST=fsmonitor-all and run your tests.
12
+#
13
+
14
+# Note, after "git reset --hard HEAD" no extensions exist other than 'TREE'
15
+# "git update-index --fsmonitor" can be used to get the extension written
16
+# before testing the results.
17
+
18
+clean_repo () {
19
+ git reset --hard HEAD &&
20
+ git clean -fd
21
+}
22
+
23
+dirty_repo () {
24
+ : >untracked &&
25
+ : >dir1/untracked &&
26
+ : >dir2/untracked &&
27
+ echo 1 >modified &&
28
+ echo 2 >dir1/modified &&
29
+ echo 3 >dir2/modified &&
30
+ echo 4 >new &&
31
+ echo 5 >dir1/new &&
32
+ echo 6 >dir2/new
33
+}
34
+
35
+write_integration_script () {
36
+ write_script .git/hooks/fsmonitor-test<<-\EOF
37
+ if test "$#" -ne 2
38
+ then
39
+ echo "$0: exactly 2 arguments expected"
40
+ exit 2
41
+ fi
42
+ if test "$1" != 1
43
+ then
44
+ echo "Unsupported core.fsmonitor hook version." >&2
45
+ exit 1
46
+ fi
47
+ printf "untracked\0"
48
+ printf "dir1/untracked\0"
49
+ printf "dir2/untracked\0"
50
+ printf "modified\0"
51
+ printf "dir1/modified\0"
52
+ printf "dir2/modified\0"
53
+ printf "new\0"
54
+ printf "dir1/new\0"
55
+ printf "dir2/new\0"
56
+ EOF
57
+}
58
+
59
+test_lazy_prereq UNTRACKED_CACHE '
60
+ { git update-index --test-untracked-cache; ret=$?; } &&
61
+ test $ret -ne 1
62
+'
63
+
64
+test_expect_success 'setup' '
65
+ mkdir -p .git/hooks &&
66
+ : >tracked &&
67
+ : >modified &&
68
+ mkdir dir1 &&
69
+ : >dir1/tracked &&
70
+ : >dir1/modified &&
71
+ mkdir dir2 &&
72
+ : >dir2/tracked &&
73
+ : >dir2/modified &&
74
+ git -c core.fsmonitor= add . &&
75
+ git -c core.fsmonitor= commit -m initial &&
76
+ git config core.fsmonitor .git/hooks/fsmonitor-test &&
77
+ cat >.gitignore <<-\EOF
78
+ .gitignore
79
+ expect*
80
+ actual*
81
+ marker*
82
+ EOF
83
+'
84
+
85
+# test that the fsmonitor extension is off by default
86
+test_expect_success 'fsmonitor extension is off by default' '
87
+ test-dump-fsmonitor >actual &&
88
+ grep "^no fsmonitor" actual
89
+'
90
+
91
+# test that "update-index --fsmonitor" adds the fsmonitor extension
92
+test_expect_success 'update-index --fsmonitor" adds the fsmonitor extension' '
93
+ git update-index --fsmonitor &&
94
+ test-dump-fsmonitor >actual &&
95
+ grep "^fsmonitor last update" actual
96
+'
97
+
98
+# test that "update-index --no-fsmonitor" removes the fsmonitor extension
99
+test_expect_success 'update-index --no-fsmonitor" removes the fsmonitor extension' '
100
+ git update-index --no-fsmonitor &&
101
+ test-dump-fsmonitor >actual &&
102
+ grep "^no fsmonitor" actual
103
+'
104
+
105
+cat >expect <<EOF &&
106
+h dir1/modified
107
+H dir1/tracked
108
+h dir2/modified
109
+H dir2/tracked
110
+h modified
111
+H tracked
112
+EOF
113
+
114
+# test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit
115
+test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' '
116
+ git update-index --fsmonitor &&
117
+ git update-index --fsmonitor-valid dir1/modified &&
118
+ git update-index --fsmonitor-valid dir2/modified &&
119
+ git update-index --fsmonitor-valid modified &&
120
+ git ls-files -f >actual &&
121
+ test_cmp expect actual
122
+'
123
+
124
+cat >expect <<EOF &&
125
+H dir1/modified
126
+H dir1/tracked
127
+H dir2/modified
128
+H dir2/tracked
129
+H modified
130
+H tracked
131
+EOF
132
+
133
+# test that "update-index --no-fsmonitor-valid" clears the fsmonitor valid bit
134
+test_expect_success 'update-index --no-fsmonitor-valid" clears the fsmonitor valid bit' '
135
+ git update-index --no-fsmonitor-valid dir1/modified &&
136
+ git update-index --no-fsmonitor-valid dir2/modified &&
137
+ git update-index --no-fsmonitor-valid modified &&
138
+ git ls-files -f >actual &&
139
+ test_cmp expect actual
140
+'
141
+
142
+cat >expect <<EOF &&
143
+H dir1/modified
144
+H dir1/tracked
145
+H dir2/modified
146
+H dir2/tracked
147
+H modified
148
+H tracked
149
+EOF
150
+
151
+# test that all files returned by the script get flagged as invalid
152
+test_expect_success 'all files returned by integration script get flagged as invalid' '
153
+ write_integration_script &&
154
+ dirty_repo &&
155
+ git update-index --fsmonitor &&
156
+ git ls-files -f >actual &&
157
+ test_cmp expect actual
158
+'
159
+
160
+cat >expect <<EOF &&
161
+H dir1/modified
162
+h dir1/new
163
+H dir1/tracked
164
+H dir2/modified
165
+h dir2/new
166
+H dir2/tracked
167
+H modified
168
+h new
169
+H tracked
170
+EOF
171
+
172
+# test that newly added files are marked valid
173
+test_expect_success 'newly added files are marked valid' '
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 &&
213
+ printf "dir1/modified\0"
214
+ EOF
215
+ clean_repo &&
216
+ git update-index --refresh --force-write-index &&
217
+ echo 1 >modified &&
218
+ echo 2 >dir1/modified &&
219
+ echo 3 >dir2/modified &&
220
+ test_must_fail git update-index --refresh --force-write-index &&
221
+ git ls-files -f >actual &&
222
+ test_cmp expect actual
223
+'
224
+
225
+# Ensure commands that call refresh_index() to move the index back in time
226
+# properly invalidate the fsmonitor cache
227
+test_expect_success 'refresh_index() invalidates fsmonitor cache' '
228
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
229
+ EOF
230
+ clean_repo &&
231
+ dirty_repo &&
232
+ git add . &&
233
+ git commit -m "to reset" &&
234
+ git reset HEAD~1 &&
235
+ git status >actual &&
236
+ git -c core.fsmonitor= status >expect &&
237
+ test_i18ncmp expect actual
238
+'
239
+
240
+# test fsmonitor with and without preloadIndex
241
+preload_values="false true"
242
+for preload_val in $preload_values
243
+do
244
+ test_expect_success "setup preloadIndex to $preload_val" '
245
+ git config core.preloadIndex $preload_val &&
246
+ if test $preload_val = true
247
+ then
248
+ GIT_FORCE_PRELOAD_TEST=$preload_val; export GIT_FORCE_PRELOAD_TEST
249
+ else
250
+ unset GIT_FORCE_PRELOAD_TEST
251
+ fi
252
+ '
253
+
254
+ # test fsmonitor with and without the untracked cache (if available)
255
+ uc_values="false"
256
+ test_have_prereq UNTRACKED_CACHE && uc_values="false true"
257
+ for uc_val in $uc_values
258
+ do
259
+ test_expect_success "setup untracked cache to $uc_val" '
260
+ git config core.untrackedcache $uc_val
261
+ '
262
+
263
+ # Status is well tested elsewhere so we'll just ensure that the results are
264
+ # the same when using core.fsmonitor.
265
+ test_expect_success 'compare status with and without fsmonitor' '
266
+ write_integration_script &&
267
+ clean_repo &&
268
+ dirty_repo &&
269
+ git add new &&
270
+ git add dir1/new &&
271
+ git add dir2/new &&
272
+ git status >actual &&
273
+ git -c core.fsmonitor= status >expect &&
274
+ test_i18ncmp expect actual
275
+ '
276
+
277
+ # Make sure it's actually skipping the check for modified and untracked
278
+ # (if enabled) files unless it is told about them.
279
+ test_expect_success "status doesn't detect unreported modifications" '
280
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
281
+ :>marker
282
+ EOF
283
+ clean_repo &&
284
+ git status &&
285
+ test_path_is_file marker &&
286
+ dirty_repo &&
287
+ rm -f marker &&
288
+ git status >actual &&
289
+ test_path_is_file marker &&
290
+ test_i18ngrep ! "Changes not staged for commit:" actual &&
291
+ if test $uc_val = true
292
+ then
293
+ test_i18ngrep ! "Untracked files:" actual
294
+ fi &&
295
+ if test $uc_val = false
296
+ then
297
+ test_i18ngrep "Untracked files:" actual
298
+ fi &&
299
+ rm -f marker
300
+ '
301
+ done
302
+done
303
+
304
+test_done