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