Merge branch 'rs/grep-no-recursive'
[git] / t / t1700-split-index.sh
1 #!/bin/sh
2
3 test_description='split index mode tests'
4
5 . ./test-lib.sh
6
7 # We need total control of index splitting here
8 sane_unset GIT_TEST_SPLIT_INDEX
9
10 # Testing a hard coded SHA against an index with an extension
11 # that can vary from run to run is problematic so we disable
12 # those extensions.
13 sane_unset GIT_TEST_FSMONITOR
14 sane_unset GIT_TEST_INDEX_THREADS
15
16 test_expect_success 'enable split index' '
17         git config splitIndex.maxPercentChange 100 &&
18         git update-index --split-index &&
19         test-tool dump-split-index .git/index >actual &&
20         indexversion=$(test-tool index-version <.git/index) &&
21         if test "$indexversion" = "4"
22         then
23                 own=3527df833c6c100d3d1d921a9a782d62a8be4b58
24                 base=746f7ab2ed44fb839efdfbffcf399d0b113fb4cb
25         else
26                 own=5e9b60117ece18da410ddecc8b8d43766a0e4204
27                 base=4370042739b31cd17a5c5cd6043a77c9a00df113
28         fi &&
29         cat >expect <<-EOF &&
30         own $own
31         base $base
32         replacements:
33         deletions:
34         EOF
35         test_cmp expect actual
36 '
37
38 test_expect_success 'add one file' '
39         : >one &&
40         git update-index --add one &&
41         git ls-files --stage >ls-files.actual &&
42         cat >ls-files.expect <<-EOF &&
43         100644 $EMPTY_BLOB 0    one
44         EOF
45         test_cmp ls-files.expect ls-files.actual &&
46
47         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
48         cat >expect <<-EOF &&
49         base $base
50         100644 $EMPTY_BLOB 0    one
51         replacements:
52         deletions:
53         EOF
54         test_cmp expect actual
55 '
56
57 test_expect_success 'disable split index' '
58         git update-index --no-split-index &&
59         git ls-files --stage >ls-files.actual &&
60         cat >ls-files.expect <<-EOF &&
61         100644 $EMPTY_BLOB 0    one
62         EOF
63         test_cmp ls-files.expect ls-files.actual &&
64
65         BASE=$(test-tool dump-split-index .git/index | sed -n "s/^own/base/p") &&
66         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
67         cat >expect <<-EOF &&
68         not a split index
69         EOF
70         test_cmp expect actual
71 '
72
73 test_expect_success 'enable split index again, "one" now belongs to base index"' '
74         git update-index --split-index &&
75         git ls-files --stage >ls-files.actual &&
76         cat >ls-files.expect <<-EOF &&
77         100644 $EMPTY_BLOB 0    one
78         EOF
79         test_cmp ls-files.expect ls-files.actual &&
80
81         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
82         cat >expect <<-EOF &&
83         $BASE
84         replacements:
85         deletions:
86         EOF
87         test_cmp expect actual
88 '
89
90 test_expect_success 'modify original file, base index untouched' '
91         echo modified >one &&
92         git update-index one &&
93         git ls-files --stage >ls-files.actual &&
94         cat >ls-files.expect <<-EOF &&
95         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0       one
96         EOF
97         test_cmp ls-files.expect ls-files.actual &&
98
99         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
100         q_to_tab >expect <<-EOF &&
101         $BASE
102         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
103         replacements: 0
104         deletions:
105         EOF
106         test_cmp expect actual
107 '
108
109 test_expect_success 'add another file, which stays index' '
110         : >two &&
111         git update-index --add two &&
112         git ls-files --stage >ls-files.actual &&
113         cat >ls-files.expect <<-EOF &&
114         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0       one
115         100644 $EMPTY_BLOB 0    two
116         EOF
117         test_cmp ls-files.expect ls-files.actual &&
118
119         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
120         q_to_tab >expect <<-EOF &&
121         $BASE
122         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
123         100644 $EMPTY_BLOB 0    two
124         replacements: 0
125         deletions:
126         EOF
127         test_cmp expect actual
128 '
129
130 test_expect_success 'remove file not in base index' '
131         git update-index --force-remove two &&
132         git ls-files --stage >ls-files.actual &&
133         cat >ls-files.expect <<-EOF &&
134         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0       one
135         EOF
136         test_cmp ls-files.expect ls-files.actual &&
137
138         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
139         q_to_tab >expect <<-EOF &&
140         $BASE
141         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
142         replacements: 0
143         deletions:
144         EOF
145         test_cmp expect actual
146 '
147
148 test_expect_success 'remove file in base index' '
149         git update-index --force-remove one &&
150         git ls-files --stage >ls-files.actual &&
151         test_must_be_empty ls-files.actual &&
152
153         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
154         cat >expect <<-EOF &&
155         $BASE
156         replacements:
157         deletions: 0
158         EOF
159         test_cmp expect actual
160 '
161
162 test_expect_success 'add original file back' '
163         : >one &&
164         git update-index --add one &&
165         git ls-files --stage >ls-files.actual &&
166         cat >ls-files.expect <<-EOF &&
167         100644 $EMPTY_BLOB 0    one
168         EOF
169         test_cmp ls-files.expect ls-files.actual &&
170
171         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
172         cat >expect <<-EOF &&
173         $BASE
174         100644 $EMPTY_BLOB 0    one
175         replacements:
176         deletions: 0
177         EOF
178         test_cmp expect actual
179 '
180
181 test_expect_success 'add new file' '
182         : >two &&
183         git update-index --add two &&
184         git ls-files --stage >actual &&
185         cat >expect <<-EOF &&
186         100644 $EMPTY_BLOB 0    one
187         100644 $EMPTY_BLOB 0    two
188         EOF
189         test_cmp expect actual
190 '
191
192 test_expect_success 'unify index, two files remain' '
193         git update-index --no-split-index &&
194         git ls-files --stage >ls-files.actual &&
195         cat >ls-files.expect <<-EOF &&
196         100644 $EMPTY_BLOB 0    one
197         100644 $EMPTY_BLOB 0    two
198         EOF
199         test_cmp ls-files.expect ls-files.actual &&
200
201         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
202         cat >expect <<-EOF &&
203         not a split index
204         EOF
205         test_cmp expect actual
206 '
207
208 test_expect_success 'rev-parse --shared-index-path' '
209         test_create_repo split-index &&
210         (
211                 cd split-index &&
212                 git update-index --split-index &&
213                 echo .git/sharedindex* >expect &&
214                 git rev-parse --shared-index-path >actual &&
215                 test_cmp expect actual &&
216                 mkdir subdirectory &&
217                 cd subdirectory &&
218                 echo ../.git/sharedindex* >expect &&
219                 git rev-parse --shared-index-path >actual &&
220                 test_cmp expect actual
221         )
222 '
223
224 test_expect_success 'set core.splitIndex config variable to true' '
225         git config core.splitIndex true &&
226         : >three &&
227         git update-index --add three &&
228         git ls-files --stage >ls-files.actual &&
229         cat >ls-files.expect <<-EOF &&
230         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
231         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       three
232         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
233         EOF
234         test_cmp ls-files.expect ls-files.actual &&
235         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
236         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
237         cat >expect <<-EOF &&
238         $BASE
239         replacements:
240         deletions:
241         EOF
242         test_cmp expect actual
243 '
244
245 test_expect_success 'set core.splitIndex config variable to false' '
246         git config core.splitIndex false &&
247         git update-index --force-remove three &&
248         git ls-files --stage >ls-files.actual &&
249         cat >ls-files.expect <<-EOF &&
250         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
251         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
252         EOF
253         test_cmp ls-files.expect ls-files.actual &&
254         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
255         cat >expect <<-EOF &&
256         not a split index
257         EOF
258         test_cmp expect actual
259 '
260
261 test_expect_success 'set core.splitIndex config variable to true' '
262         git config core.splitIndex true &&
263         : >three &&
264         git update-index --add three &&
265         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
266         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
267         cat >expect <<-EOF &&
268         $BASE
269         replacements:
270         deletions:
271         EOF
272         test_cmp expect actual &&
273         : >four &&
274         git update-index --add four &&
275         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
276         cat >expect <<-EOF &&
277         $BASE
278         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       four
279         replacements:
280         deletions:
281         EOF
282         test_cmp expect actual
283 '
284
285 test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
286         git config --unset splitIndex.maxPercentChange &&
287         : >five &&
288         git update-index --add five &&
289         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
290         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
291         cat >expect <<-EOF &&
292         $BASE
293         replacements:
294         deletions:
295         EOF
296         test_cmp expect actual &&
297         : >six &&
298         git update-index --add six &&
299         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
300         cat >expect <<-EOF &&
301         $BASE
302         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       six
303         replacements:
304         deletions:
305         EOF
306         test_cmp expect actual
307 '
308
309 test_expect_success 'check splitIndex.maxPercentChange set to 0' '
310         git config splitIndex.maxPercentChange 0 &&
311         : >seven &&
312         git update-index --add seven &&
313         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
314         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
315         cat >expect <<-EOF &&
316         $BASE
317         replacements:
318         deletions:
319         EOF
320         test_cmp expect actual &&
321         : >eight &&
322         git update-index --add eight &&
323         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
324         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
325         cat >expect <<-EOF &&
326         $BASE
327         replacements:
328         deletions:
329         EOF
330         test_cmp expect actual
331 '
332
333 test_expect_success 'shared index files expire after 2 weeks by default' '
334         : >ten &&
335         git update-index --add ten &&
336         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
337         just_under_2_weeks_ago=$((5-14*86400)) &&
338         test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
339         : >eleven &&
340         git update-index --add eleven &&
341         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
342         just_over_2_weeks_ago=$((-1-14*86400)) &&
343         test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
344         : >twelve &&
345         git update-index --add twelve &&
346         test $(ls .git/sharedindex.* | wc -l) -le 2
347 '
348
349 test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
350         git config splitIndex.sharedIndexExpire "16.days.ago" &&
351         test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
352         : >thirteen &&
353         git update-index --add thirteen &&
354         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
355         just_over_16_days_ago=$((-1-16*86400)) &&
356         test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
357         : >fourteen &&
358         git update-index --add fourteen &&
359         test $(ls .git/sharedindex.* | wc -l) -le 2
360 '
361
362 test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
363         git config splitIndex.sharedIndexExpire never &&
364         just_10_years_ago=$((-365*10*86400)) &&
365         test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
366         : >fifteen &&
367         git update-index --add fifteen &&
368         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
369         git config splitIndex.sharedIndexExpire now &&
370         just_1_second_ago=-1 &&
371         test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
372         : >sixteen &&
373         git update-index --add sixteen &&
374         test $(ls .git/sharedindex.* | wc -l) -le 2
375 '
376
377 while read -r mode modebits
378 do
379         test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
380                 # Remove existing shared index files
381                 git config core.splitIndex false &&
382                 git update-index --force-remove one &&
383                 rm -f .git/sharedindex.* &&
384                 # Create one new shared index file
385                 git config core.sharedrepository "$mode" &&
386                 git config core.splitIndex true &&
387                 : >one &&
388                 git update-index --add one &&
389                 echo "$modebits" >expect &&
390                 test_modebits .git/index >actual &&
391                 test_cmp expect actual &&
392                 shared=$(ls .git/sharedindex.*) &&
393                 case "$shared" in
394                 *" "*)
395                         # we have more than one???
396                         false ;;
397                 *)
398                         test_modebits "$shared" >actual &&
399                         test_cmp expect actual ;;
400                 esac
401         '
402 done <<\EOF
403 0666 -rw-rw-rw-
404 0642 -rw-r---w-
405 EOF
406
407 test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
408         test_create_repo ro &&
409         (
410                 cd ro &&
411                 test_commit initial &&
412                 git update-index --split-index &&
413                 test -f .git/sharedindex.*
414         ) &&
415         cp ro/.git/index new-index &&
416         test_when_finished "chmod u+w ro/.git" &&
417         chmod u-w ro/.git &&
418         GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
419         chmod u+w ro/.git &&
420         rm ro/.git/sharedindex.* &&
421         GIT_INDEX_FILE=new-index git ls-files >actual &&
422         echo initial.t >expected &&
423         test_cmp expected actual
424 '
425
426 test_expect_success 'writing split index with null sha1 does not write cache tree' '
427         git config core.splitIndex true &&
428         git config splitIndex.maxPercentChange 0 &&
429         git commit -m "commit" &&
430         {
431                 git ls-tree HEAD &&
432                 printf "160000 commit $ZERO_OID\\tbroken\\n"
433         } >broken-tree &&
434         echo "add broken entry" >msg &&
435
436         tree=$(git mktree <broken-tree) &&
437         test_tick &&
438         commit=$(git commit-tree $tree -p HEAD <msg) &&
439         git update-ref HEAD "$commit" &&
440         GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
441         test_might_fail test-tool dump-cache-tree >cache-tree.out &&
442         test_line_count = 0 cache-tree.out
443 '
444
445 test_done