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