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 '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) &&
29 # NEEDSWORK: Stop hard-coding checksums.
30 if test "$indexversion" = "4"
32 own=432ef4b63f32193984f339431fd50ca796493569
33 base=508851a7f0dfa8691e9f69c7f055865389012491
35 own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339
36 base=39d890139ee5356c7ef572216cebcd27aa41f9df
45 test_cmp expect actual
48 test_expect_success 'add one file' '
49 create_non_racy_file one &&
50 git update-index --add one &&
51 git ls-files --stage >ls-files.actual &&
52 cat >ls-files.expect <<-EOF &&
53 100644 $EMPTY_BLOB 0 one
55 test_cmp ls-files.expect ls-files.actual &&
57 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
60 100644 $EMPTY_BLOB 0 one
64 test_cmp expect actual
67 test_expect_success 'disable split index' '
68 git update-index --no-split-index &&
69 git ls-files --stage >ls-files.actual &&
70 cat >ls-files.expect <<-EOF &&
71 100644 $EMPTY_BLOB 0 one
73 test_cmp ls-files.expect ls-files.actual &&
75 BASE=$(test-tool dump-split-index .git/index | sed -n "s/^own/base/p") &&
76 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
80 test_cmp expect actual
83 test_expect_success 'enable split index again, "one" now belongs to base index"' '
84 git update-index --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 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
97 test_cmp expect actual
100 test_expect_success 'modify original file, base index untouched' '
101 echo modified | create_non_racy_file one &&
102 git update-index one &&
103 git ls-files --stage >ls-files.actual &&
104 cat >ls-files.expect <<-EOF &&
105 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
107 test_cmp ls-files.expect ls-files.actual &&
109 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
110 q_to_tab >expect <<-EOF &&
112 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
116 test_cmp expect actual
119 test_expect_success 'add another file, which stays index' '
120 create_non_racy_file two &&
121 git update-index --add two &&
122 git ls-files --stage >ls-files.actual &&
123 cat >ls-files.expect <<-EOF &&
124 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
125 100644 $EMPTY_BLOB 0 two
127 test_cmp ls-files.expect ls-files.actual &&
129 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
130 q_to_tab >expect <<-EOF &&
132 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
133 100644 $EMPTY_BLOB 0 two
137 test_cmp expect actual
140 test_expect_success 'remove file not in base index' '
141 git update-index --force-remove two &&
142 git ls-files --stage >ls-files.actual &&
143 cat >ls-files.expect <<-EOF &&
144 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
146 test_cmp ls-files.expect ls-files.actual &&
148 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
149 q_to_tab >expect <<-EOF &&
151 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
155 test_cmp expect actual
158 test_expect_success 'remove file in base index' '
159 git update-index --force-remove one &&
160 git ls-files --stage >ls-files.actual &&
161 test_must_be_empty ls-files.actual &&
163 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
164 cat >expect <<-EOF &&
169 test_cmp expect actual
172 test_expect_success 'add original file back' '
173 create_non_racy_file one &&
174 git update-index --add one &&
175 git ls-files --stage >ls-files.actual &&
176 cat >ls-files.expect <<-EOF &&
177 100644 $EMPTY_BLOB 0 one
179 test_cmp ls-files.expect ls-files.actual &&
181 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
182 cat >expect <<-EOF &&
184 100644 $EMPTY_BLOB 0 one
188 test_cmp expect actual
191 test_expect_success 'add new file' '
192 create_non_racy_file two &&
193 git update-index --add two &&
194 git ls-files --stage >actual &&
195 cat >expect <<-EOF &&
196 100644 $EMPTY_BLOB 0 one
197 100644 $EMPTY_BLOB 0 two
199 test_cmp expect actual
202 test_expect_success 'unify index, two files remain' '
203 git update-index --no-split-index &&
204 git ls-files --stage >ls-files.actual &&
205 cat >ls-files.expect <<-EOF &&
206 100644 $EMPTY_BLOB 0 one
207 100644 $EMPTY_BLOB 0 two
209 test_cmp ls-files.expect ls-files.actual &&
211 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
212 cat >expect <<-EOF &&
215 test_cmp expect actual
218 test_expect_success 'rev-parse --shared-index-path' '
219 test_create_repo split-index &&
222 git update-index --split-index &&
223 echo .git/sharedindex* >expect &&
224 git rev-parse --shared-index-path >actual &&
225 test_cmp expect actual &&
226 mkdir subdirectory &&
228 echo ../.git/sharedindex* >expect &&
229 git rev-parse --shared-index-path >actual &&
230 test_cmp expect actual
234 test_expect_success 'set core.splitIndex config variable to true' '
235 git config core.splitIndex true &&
236 create_non_racy_file three &&
237 git update-index --add three &&
238 git ls-files --stage >ls-files.actual &&
239 cat >ls-files.expect <<-EOF &&
240 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one
241 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 three
242 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two
244 test_cmp ls-files.expect ls-files.actual &&
245 BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
246 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
247 cat >expect <<-EOF &&
252 test_cmp expect actual
255 test_expect_success 'set core.splitIndex config variable to false' '
256 git config core.splitIndex false &&
257 git update-index --force-remove three &&
258 git ls-files --stage >ls-files.actual &&
259 cat >ls-files.expect <<-EOF &&
260 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one
261 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two
263 test_cmp ls-files.expect ls-files.actual &&
264 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
265 cat >expect <<-EOF &&
268 test_cmp expect actual
271 test_expect_success 'set core.splitIndex config variable back to true' '
272 git config core.splitIndex true &&
273 create_non_racy_file three &&
274 git update-index --add three &&
275 BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
276 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
277 cat >expect <<-EOF &&
282 test_cmp expect actual &&
283 create_non_racy_file four &&
284 git update-index --add four &&
285 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
286 cat >expect <<-EOF &&
288 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 four
292 test_cmp expect actual
295 test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
296 git config --unset splitIndex.maxPercentChange &&
297 create_non_racy_file five &&
298 git update-index --add five &&
299 BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
300 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
301 cat >expect <<-EOF &&
306 test_cmp expect actual &&
307 create_non_racy_file six &&
308 git update-index --add six &&
309 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
310 cat >expect <<-EOF &&
312 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 six
316 test_cmp expect actual
319 test_expect_success 'check splitIndex.maxPercentChange set to 0' '
320 git config splitIndex.maxPercentChange 0 &&
321 create_non_racy_file seven &&
322 git update-index --add seven &&
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 &&
330 test_cmp expect actual &&
331 create_non_racy_file eight &&
332 git update-index --add eight &&
333 BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
334 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
335 cat >expect <<-EOF &&
340 test_cmp expect actual
343 test_expect_success 'shared index files expire after 2 weeks by default' '
344 create_non_racy_file ten &&
345 git update-index --add ten &&
346 test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
347 just_under_2_weeks_ago=$((5-14*86400)) &&
348 test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
349 create_non_racy_file eleven &&
350 git update-index --add eleven &&
351 test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
352 just_over_2_weeks_ago=$((-1-14*86400)) &&
353 test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
354 create_non_racy_file twelve &&
355 git update-index --add twelve &&
356 test $(ls .git/sharedindex.* | wc -l) -le 2
359 test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
360 git config splitIndex.sharedIndexExpire "16.days.ago" &&
361 test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
362 create_non_racy_file thirteen &&
363 git update-index --add thirteen &&
364 test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
365 just_over_16_days_ago=$((-1-16*86400)) &&
366 test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
367 create_non_racy_file fourteen &&
368 git update-index --add fourteen &&
369 test $(ls .git/sharedindex.* | wc -l) -le 2
372 test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
373 git config splitIndex.sharedIndexExpire never &&
374 just_10_years_ago=$((-365*10*86400)) &&
375 test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
376 create_non_racy_file fifteen &&
377 git update-index --add fifteen &&
378 test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
379 git config splitIndex.sharedIndexExpire now &&
380 just_1_second_ago=-1 &&
381 test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
382 create_non_racy_file sixteen &&
383 git update-index --add sixteen &&
384 test $(ls .git/sharedindex.* | wc -l) -le 2
387 test_expect_success POSIXPERM 'same mode for index & split index' '
388 git init same-mode &&
392 test_modebits .git/index >index_mode &&
393 test_must_fail git config core.sharedRepository &&
394 git -c core.splitIndex=true status &&
395 shared=$(ls .git/sharedindex.*) &&
398 # we have more than one???
401 test_modebits "$shared" >split_index_mode &&
402 test_cmp index_mode split_index_mode ;;
407 while read -r mode modebits
409 test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
410 # Remove existing shared index files
411 git config core.splitIndex false &&
412 git update-index --force-remove one &&
413 rm -f .git/sharedindex.* &&
414 # Create one new shared index file
415 git config core.sharedrepository "$mode" &&
416 git config core.splitIndex true &&
417 create_non_racy_file one &&
418 git update-index --add one &&
419 echo "$modebits" >expect &&
420 test_modebits .git/index >actual &&
421 test_cmp expect actual &&
422 shared=$(ls .git/sharedindex.*) &&
425 # we have more than one???
428 test_modebits "$shared" >actual &&
429 test_cmp expect actual ;;
437 test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
438 test_create_repo ro &&
441 test_commit initial &&
442 git update-index --split-index &&
443 test -f .git/sharedindex.*
445 cp ro/.git/index new-index &&
446 test_when_finished "chmod u+w ro/.git" &&
448 GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
450 rm ro/.git/sharedindex.* &&
451 GIT_INDEX_FILE=new-index git ls-files >actual &&
452 echo initial.t >expected &&
453 test_cmp expected actual
456 test_expect_success 'writing split index with null sha1 does not write cache tree' '
457 git config core.splitIndex true &&
458 git config splitIndex.maxPercentChange 0 &&
459 git commit -m "commit" &&
462 printf "160000 commit $ZERO_OID\\tbroken\\n"
464 echo "add broken entry" >msg &&
466 tree=$(git mktree <broken-tree) &&
468 commit=$(git commit-tree $tree -p HEAD <msg) &&
469 git update-ref HEAD "$commit" &&
470 GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
471 test_might_fail test-tool dump-cache-tree >cache-tree.out &&
472 test_line_count = 0 cache-tree.out
475 test_expect_success 'do not refresh null base index' '
476 test_create_repo merge &&
479 test_commit initial &&
480 git checkout -b side-branch &&
482 git checkout master &&
483 git update-index --split-index &&
485 # must not write a new shareindex, or we wont catch the problem
486 git -c splitIndex.maxPercentChange=100 merge --no-edit side-branch 2>err &&
487 # i.e. do not expect warnings like
488 # could not freshen shared index .../shareindex.00000...
489 test_must_be_empty err