3 test_description='split index mode tests'
7 # We need total control of index splitting here
8 sane_unset GIT_TEST_SPLIT_INDEX
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
13 sane_unset GIT_TEST_FSMONITOR
14 sane_unset GIT_TEST_INDEX_THREADS
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 () {
20 test-tool chmtime =-5 "$1"
23 test_expect_success 'setup' '
25 own_v3 sha1:8299b0bcd1ac364e5f1d7768efb62fa2da79a339
26 own_v3 sha256:38a6d2925e3eceec33ad7b34cbff4e0086caa0daf28f31e51f5bd94b4a7af86b
28 base_v3 sha1:39d890139ee5356c7ef572216cebcd27aa41f9df
29 base_v3 sha256:c9baeadf905112bf6c17aefbd7d02267afd70ded613c30cafed2d40cb506e1ed
31 own_v4 sha1:432ef4b63f32193984f339431fd50ca796493569
32 own_v4 sha256:6738ac6319c25b694afa7bcc313deb182d1a59b68bf7a47b4296de83478c0420
34 base_v4 sha1:508851a7f0dfa8691e9f69c7f055865389012491
35 base_v4 sha256:3177d4adfdd4b6904f7e921d91d715a471c0dde7cf6a4bba574927f02b699508
39 test_expect_success 'enable split index' '
40 git config splitIndex.maxPercentChange 100 &&
41 git update-index --split-index &&
42 test-tool dump-split-index .git/index >actual &&
43 indexversion=$(test-tool index-version <.git/index) &&
45 # NEEDSWORK: Stop hard-coding checksums.
46 if test "$indexversion" = "4"
48 own=$(test_oid own_v4)
49 base=$(test_oid base_v4)
51 own=$(test_oid own_v3)
52 base=$(test_oid base_v3)
61 test_cmp expect actual
64 test_expect_success 'add one file' '
65 create_non_racy_file one &&
66 git update-index --add one &&
67 git ls-files --stage >ls-files.actual &&
68 cat >ls-files.expect <<-EOF &&
69 100644 $EMPTY_BLOB 0 one
71 test_cmp ls-files.expect ls-files.actual &&
73 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
76 100644 $EMPTY_BLOB 0 one
80 test_cmp expect actual
83 test_expect_success 'disable split index' '
84 git update-index --no-split-index &&
85 git ls-files --stage >ls-files.actual &&
86 cat >ls-files.expect <<-EOF &&
87 100644 $EMPTY_BLOB 0 one
89 test_cmp ls-files.expect ls-files.actual &&
91 BASE=$(test-tool dump-split-index .git/index | sed -n "s/^own/base/p") &&
92 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
96 test_cmp expect actual
99 test_expect_success 'enable split index again, "one" now belongs to base index"' '
100 git update-index --split-index &&
101 git ls-files --stage >ls-files.actual &&
102 cat >ls-files.expect <<-EOF &&
103 100644 $EMPTY_BLOB 0 one
105 test_cmp ls-files.expect ls-files.actual &&
107 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
108 cat >expect <<-EOF &&
113 test_cmp expect actual
116 test_expect_success 'modify original file, base index untouched' '
117 echo modified | create_non_racy_file one &&
118 file1_blob=$(git hash-object one) &&
119 git update-index one &&
120 git ls-files --stage >ls-files.actual &&
121 cat >ls-files.expect <<-EOF &&
122 100644 $file1_blob 0 one
124 test_cmp ls-files.expect ls-files.actual &&
126 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
127 q_to_tab >expect <<-EOF &&
129 100644 $file1_blob 0Q
133 test_cmp expect actual
136 test_expect_success 'add another file, which stays index' '
137 create_non_racy_file two &&
138 git update-index --add two &&
139 git ls-files --stage >ls-files.actual &&
140 cat >ls-files.expect <<-EOF &&
141 100644 $file1_blob 0 one
142 100644 $EMPTY_BLOB 0 two
144 test_cmp ls-files.expect ls-files.actual &&
146 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
147 q_to_tab >expect <<-EOF &&
149 100644 $file1_blob 0Q
150 100644 $EMPTY_BLOB 0 two
154 test_cmp expect actual
157 test_expect_success 'remove file not in base index' '
158 git update-index --force-remove two &&
159 git ls-files --stage >ls-files.actual &&
160 cat >ls-files.expect <<-EOF &&
161 100644 $file1_blob 0 one
163 test_cmp ls-files.expect ls-files.actual &&
165 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
166 q_to_tab >expect <<-EOF &&
168 100644 $file1_blob 0Q
172 test_cmp expect actual
175 test_expect_success 'remove file in base index' '
176 git update-index --force-remove one &&
177 git ls-files --stage >ls-files.actual &&
178 test_must_be_empty ls-files.actual &&
180 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
181 cat >expect <<-EOF &&
186 test_cmp expect actual
189 test_expect_success 'add original file back' '
190 create_non_racy_file one &&
191 git update-index --add one &&
192 git ls-files --stage >ls-files.actual &&
193 cat >ls-files.expect <<-EOF &&
194 100644 $EMPTY_BLOB 0 one
196 test_cmp ls-files.expect ls-files.actual &&
198 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
199 cat >expect <<-EOF &&
201 100644 $EMPTY_BLOB 0 one
205 test_cmp expect actual
208 test_expect_success 'add new file' '
209 create_non_racy_file two &&
210 git update-index --add two &&
211 git ls-files --stage >actual &&
212 cat >expect <<-EOF &&
213 100644 $EMPTY_BLOB 0 one
214 100644 $EMPTY_BLOB 0 two
216 test_cmp expect actual
219 test_expect_success 'unify index, two files remain' '
220 git update-index --no-split-index &&
221 git ls-files --stage >ls-files.actual &&
222 cat >ls-files.expect <<-EOF &&
223 100644 $EMPTY_BLOB 0 one
224 100644 $EMPTY_BLOB 0 two
226 test_cmp ls-files.expect ls-files.actual &&
228 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
229 cat >expect <<-EOF &&
232 test_cmp expect actual
235 test_expect_success 'rev-parse --shared-index-path' '
236 test_create_repo split-index &&
239 git update-index --split-index &&
240 echo .git/sharedindex* >expect &&
241 git rev-parse --shared-index-path >actual &&
242 test_cmp expect actual &&
243 mkdir subdirectory &&
245 echo ../.git/sharedindex* >expect &&
246 git rev-parse --shared-index-path >actual &&
247 test_cmp expect actual
251 test_expect_success 'set core.splitIndex config variable to true' '
252 git config core.splitIndex true &&
253 create_non_racy_file three &&
254 git update-index --add three &&
255 git ls-files --stage >ls-files.actual &&
256 cat >ls-files.expect <<-EOF &&
257 100644 $EMPTY_BLOB 0 one
258 100644 $EMPTY_BLOB 0 three
259 100644 $EMPTY_BLOB 0 two
261 test_cmp ls-files.expect ls-files.actual &&
262 BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
263 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
264 cat >expect <<-EOF &&
269 test_cmp expect actual
272 test_expect_success 'set core.splitIndex config variable to false' '
273 git config core.splitIndex false &&
274 git update-index --force-remove three &&
275 git ls-files --stage >ls-files.actual &&
276 cat >ls-files.expect <<-EOF &&
277 100644 $EMPTY_BLOB 0 one
278 100644 $EMPTY_BLOB 0 two
280 test_cmp ls-files.expect ls-files.actual &&
281 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
282 cat >expect <<-EOF &&
285 test_cmp expect actual
288 test_expect_success 'set core.splitIndex config variable back to true' '
289 git config core.splitIndex true &&
290 create_non_racy_file three &&
291 git update-index --add three &&
292 BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
293 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
294 cat >expect <<-EOF &&
299 test_cmp expect actual &&
300 create_non_racy_file four &&
301 git update-index --add four &&
302 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
303 cat >expect <<-EOF &&
305 100644 $EMPTY_BLOB 0 four
309 test_cmp expect actual
312 test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
313 git config --unset splitIndex.maxPercentChange &&
314 create_non_racy_file five &&
315 git update-index --add five &&
316 BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
317 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
318 cat >expect <<-EOF &&
323 test_cmp expect actual &&
324 create_non_racy_file six &&
325 git update-index --add six &&
326 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
327 cat >expect <<-EOF &&
329 100644 $EMPTY_BLOB 0 six
333 test_cmp expect actual
336 test_expect_success 'check splitIndex.maxPercentChange set to 0' '
337 git config splitIndex.maxPercentChange 0 &&
338 create_non_racy_file seven &&
339 git update-index --add seven &&
340 BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
341 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
342 cat >expect <<-EOF &&
347 test_cmp expect actual &&
348 create_non_racy_file eight &&
349 git update-index --add eight &&
350 BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
351 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
352 cat >expect <<-EOF &&
357 test_cmp expect actual
360 test_expect_success 'shared index files expire after 2 weeks by default' '
361 create_non_racy_file ten &&
362 git update-index --add ten &&
363 test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
364 just_under_2_weeks_ago=$((5-14*86400)) &&
365 test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
366 create_non_racy_file eleven &&
367 git update-index --add eleven &&
368 test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
369 just_over_2_weeks_ago=$((-1-14*86400)) &&
370 test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
371 create_non_racy_file twelve &&
372 git update-index --add twelve &&
373 test $(ls .git/sharedindex.* | wc -l) -le 2
376 test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
377 git config splitIndex.sharedIndexExpire "16.days.ago" &&
378 test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
379 create_non_racy_file thirteen &&
380 git update-index --add thirteen &&
381 test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
382 just_over_16_days_ago=$((-1-16*86400)) &&
383 test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
384 create_non_racy_file fourteen &&
385 git update-index --add fourteen &&
386 test $(ls .git/sharedindex.* | wc -l) -le 2
389 test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
390 git config splitIndex.sharedIndexExpire never &&
391 just_10_years_ago=$((-365*10*86400)) &&
392 test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
393 create_non_racy_file fifteen &&
394 git update-index --add fifteen &&
395 test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
396 git config splitIndex.sharedIndexExpire now &&
397 just_1_second_ago=-1 &&
398 test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
399 create_non_racy_file sixteen &&
400 git update-index --add sixteen &&
401 test $(ls .git/sharedindex.* | wc -l) -le 2
404 test_expect_success POSIXPERM 'same mode for index & split index' '
405 git init same-mode &&
409 test_modebits .git/index >index_mode &&
410 test_must_fail git config core.sharedRepository &&
411 git -c core.splitIndex=true status &&
412 shared=$(ls .git/sharedindex.*) &&
415 # we have more than one???
418 test_modebits "$shared" >split_index_mode &&
419 test_cmp index_mode split_index_mode ;;
424 while read -r mode modebits
426 test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
427 # Remove existing shared index files
428 git config core.splitIndex false &&
429 git update-index --force-remove one &&
430 rm -f .git/sharedindex.* &&
431 # Create one new shared index file
432 git config core.sharedrepository "$mode" &&
433 git config core.splitIndex true &&
434 create_non_racy_file one &&
435 git update-index --add one &&
436 echo "$modebits" >expect &&
437 test_modebits .git/index >actual &&
438 test_cmp expect actual &&
439 shared=$(ls .git/sharedindex.*) &&
442 # we have more than one???
445 test_modebits "$shared" >actual &&
446 test_cmp expect actual ;;
454 test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
455 test_create_repo ro &&
458 test_commit initial &&
459 git update-index --split-index &&
460 test -f .git/sharedindex.*
462 cp ro/.git/index new-index &&
463 test_when_finished "chmod u+w ro/.git" &&
465 GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
467 rm ro/.git/sharedindex.* &&
468 GIT_INDEX_FILE=new-index git ls-files >actual &&
469 echo initial.t >expected &&
470 test_cmp expected actual
473 test_expect_success 'writing split index with null sha1 does not write cache tree' '
474 git config core.splitIndex true &&
475 git config splitIndex.maxPercentChange 0 &&
476 git commit -m "commit" &&
479 printf "160000 commit $ZERO_OID\\tbroken\\n"
481 echo "add broken entry" >msg &&
483 tree=$(git mktree <broken-tree) &&
485 commit=$(git commit-tree $tree -p HEAD <msg) &&
486 git update-ref HEAD "$commit" &&
487 GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
488 test_might_fail test-tool dump-cache-tree >cache-tree.out &&
489 test_line_count = 0 cache-tree.out
492 test_expect_success 'do not refresh null base index' '
493 test_create_repo merge &&
496 test_commit initial &&
497 git checkout -b side-branch &&
499 git checkout master &&
500 git update-index --split-index &&
502 # must not write a new shareindex, or we wont catch the problem
503 git -c splitIndex.maxPercentChange=100 merge --no-edit side-branch 2>err &&
504 # i.e. do not expect warnings like
505 # could not freshen shared index .../shareindex.00000...
506 test_must_be_empty err