1#!/bin/sh
2
3test_description='split index mode tests'
4
5. ./test-lib.sh
6
7# We need total control of index splitting here
8sane_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.
13sane_unset GIT_TEST_FSMONITOR
14sane_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.
18create_non_racy_file () {
19 cat >"$1" &&
20 test-tool chmtime =-5 "$1"
21}
22
23test_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
29 # NEEDSWORK: Stop hard-coding checksums.
30 if test "$indexversion" = "4"
31 then
32 own=432ef4b63f32193984f339431fd50ca796493569
33 base=508851a7f0dfa8691e9f69c7f055865389012491
34 else
35 own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339
36 base=39d890139ee5356c7ef572216cebcd27aa41f9df
37 fi &&
38
39 cat >expect <<-EOF &&
40 own $own
41 base $base
42 replacements:
43 deletions:
44 EOF
45 test_cmp expect actual
46'
47
48test_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
54 EOF
55 test_cmp ls-files.expect ls-files.actual &&
56
57 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
58 cat >expect <<-EOF &&
59 base $base
60 100644 $EMPTY_BLOB 0 one
61 replacements:
62 deletions:
63 EOF
64 test_cmp expect actual
65'
66
67test_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
72 EOF
73 test_cmp ls-files.expect ls-files.actual &&
74
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 &&
77 cat >expect <<-EOF &&
78 not a split index
79 EOF
80 test_cmp expect actual
81'
82
83test_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
88 EOF
89 test_cmp ls-files.expect ls-files.actual &&
90
91 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
92 cat >expect <<-EOF &&
93 $BASE
94 replacements:
95 deletions:
96 EOF
97 test_cmp expect actual
98'
99
100test_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
106 EOF
107 test_cmp ls-files.expect ls-files.actual &&
108
109 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
110 q_to_tab >expect <<-EOF &&
111 $BASE
112 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
113 replacements: 0
114 deletions:
115 EOF
116 test_cmp expect actual
117'
118
119test_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
126 EOF
127 test_cmp ls-files.expect ls-files.actual &&
128
129 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
130 q_to_tab >expect <<-EOF &&
131 $BASE
132 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
133 100644 $EMPTY_BLOB 0 two
134 replacements: 0
135 deletions:
136 EOF
137 test_cmp expect actual
138'
139
140test_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
145 EOF
146 test_cmp ls-files.expect ls-files.actual &&
147
148 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
149 q_to_tab >expect <<-EOF &&
150 $BASE
151 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
152 replacements: 0
153 deletions:
154 EOF
155 test_cmp expect actual
156'
157
158test_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 &&
162
163 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
164 cat >expect <<-EOF &&
165 $BASE
166 replacements:
167 deletions: 0
168 EOF
169 test_cmp expect actual
170'
171
172test_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
178 EOF
179 test_cmp ls-files.expect ls-files.actual &&
180
181 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
182 cat >expect <<-EOF &&
183 $BASE
184 100644 $EMPTY_BLOB 0 one
185 replacements:
186 deletions: 0
187 EOF
188 test_cmp expect actual
189'
190
191test_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
198 EOF
199 test_cmp expect actual
200'
201
202test_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
208 EOF
209 test_cmp ls-files.expect ls-files.actual &&
210
211 test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
212 cat >expect <<-EOF &&
213 not a split index
214 EOF
215 test_cmp expect actual
216'
217
218test_expect_success 'rev-parse --shared-index-path' '
219 test_create_repo split-index &&
220 (
221 cd 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 &&
227 cd subdirectory &&
228 echo ../.git/sharedindex* >expect &&
229 git rev-parse --shared-index-path >actual &&
230 test_cmp expect actual
231 )
232'
233
234test_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
243 EOF
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 &&
248 $BASE
249 replacements:
250 deletions:
251 EOF
252 test_cmp expect actual
253'
254
255test_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
262 EOF
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 &&
266 not a split index
267 EOF
268 test_cmp expect actual
269'
270
271test_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 &&
278 $BASE
279 replacements:
280 deletions:
281 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 &&
287 $BASE
288 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 four
289 replacements:
290 deletions:
291 EOF
292 test_cmp expect actual
293'
294
295test_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 &&
302 $BASE
303 replacements:
304 deletions:
305 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 &&
311 $BASE
312 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 six
313 replacements:
314 deletions:
315 EOF
316 test_cmp expect actual
317'
318
319test_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 &&
326 $BASE
327 replacements:
328 deletions:
329 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 &&
336 $BASE
337 replacements:
338 deletions:
339 EOF
340 test_cmp expect actual
341'
342
343test_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
357'
358
359test_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
370'
371
372test_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
385'
386
387while read -r mode modebits
388do
389 test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
390 # Remove existing shared index files
391 git config core.splitIndex false &&
392 git update-index --force-remove one &&
393 rm -f .git/sharedindex.* &&
394 # Create one new shared index file
395 git config core.sharedrepository "$mode" &&
396 git config core.splitIndex true &&
397 create_non_racy_file one &&
398 git update-index --add one &&
399 echo "$modebits" >expect &&
400 test_modebits .git/index >actual &&
401 test_cmp expect actual &&
402 shared=$(ls .git/sharedindex.*) &&
403 case "$shared" in
404 *" "*)
405 # we have more than one???
406 false ;;
407 *)
408 test_modebits "$shared" >actual &&
409 test_cmp expect actual ;;
410 esac
411 '
412done <<\EOF
4130666 -rw-rw-rw-
4140642 -rw-r---w-
415EOF
416
417test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
418 test_create_repo ro &&
419 (
420 cd ro &&
421 test_commit initial &&
422 git update-index --split-index &&
423 test -f .git/sharedindex.*
424 ) &&
425 cp ro/.git/index new-index &&
426 test_when_finished "chmod u+w ro/.git" &&
427 chmod u-w ro/.git &&
428 GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
429 chmod u+w ro/.git &&
430 rm ro/.git/sharedindex.* &&
431 GIT_INDEX_FILE=new-index git ls-files >actual &&
432 echo initial.t >expected &&
433 test_cmp expected actual
434'
435
436test_expect_success 'writing split index with null sha1 does not write cache tree' '
437 git config core.splitIndex true &&
438 git config splitIndex.maxPercentChange 0 &&
439 git commit -m "commit" &&
440 {
441 git ls-tree HEAD &&
442 printf "160000 commit $ZERO_OID\\tbroken\\n"
443 } >broken-tree &&
444 echo "add broken entry" >msg &&
445
446 tree=$(git mktree <broken-tree) &&
447 test_tick &&
448 commit=$(git commit-tree $tree -p HEAD <msg) &&
449 git update-ref HEAD "$commit" &&
450 GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
451 test_might_fail test-tool dump-cache-tree >cache-tree.out &&
452 test_line_count = 0 cache-tree.out
453'
454
455test_done