read-cache: make the split index obey umask settings
[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 sane_unset GIT_FSMONITOR_TEST
10
11 test_expect_success 'enable split index' '
12         git config splitIndex.maxPercentChange 100 &&
13         git update-index --split-index &&
14         test-tool dump-split-index .git/index >actual &&
15         indexversion=$(test-tool 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
33 test_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-tool 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
52 test_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-tool dump-split-index .git/index | grep "^own" | sed "s/own/base/") &&
61         test-tool 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
68 test_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-tool 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
85 test_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-tool 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
104 test_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-tool 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
125 test_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-tool 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
143 test_expect_success 'remove file in base index' '
144         git update-index --force-remove one &&
145         git ls-files --stage >ls-files.actual &&
146         test_must_be_empty ls-files.actual &&
147
148         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
149         cat >expect <<-EOF &&
150         $BASE
151         replacements:
152         deletions: 0
153         EOF
154         test_cmp expect actual
155 '
156
157 test_expect_success 'add original file back' '
158         : >one &&
159         git update-index --add one &&
160         git ls-files --stage >ls-files.actual &&
161         cat >ls-files.expect <<-EOF &&
162         100644 $EMPTY_BLOB 0    one
163         EOF
164         test_cmp ls-files.expect ls-files.actual &&
165
166         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
167         cat >expect <<-EOF &&
168         $BASE
169         100644 $EMPTY_BLOB 0    one
170         replacements:
171         deletions: 0
172         EOF
173         test_cmp expect actual
174 '
175
176 test_expect_success 'add new file' '
177         : >two &&
178         git update-index --add two &&
179         git ls-files --stage >actual &&
180         cat >expect <<-EOF &&
181         100644 $EMPTY_BLOB 0    one
182         100644 $EMPTY_BLOB 0    two
183         EOF
184         test_cmp expect actual
185 '
186
187 test_expect_success 'unify index, two files remain' '
188         git update-index --no-split-index &&
189         git ls-files --stage >ls-files.actual &&
190         cat >ls-files.expect <<-EOF &&
191         100644 $EMPTY_BLOB 0    one
192         100644 $EMPTY_BLOB 0    two
193         EOF
194         test_cmp ls-files.expect ls-files.actual &&
195
196         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
197         cat >expect <<-EOF &&
198         not a split index
199         EOF
200         test_cmp expect actual
201 '
202
203 test_expect_success 'rev-parse --shared-index-path' '
204         test_create_repo split-index &&
205         (
206                 cd split-index &&
207                 git update-index --split-index &&
208                 echo .git/sharedindex* >expect &&
209                 git rev-parse --shared-index-path >actual &&
210                 test_cmp expect actual &&
211                 mkdir subdirectory &&
212                 cd subdirectory &&
213                 echo ../.git/sharedindex* >expect &&
214                 git rev-parse --shared-index-path >actual &&
215                 test_cmp expect actual
216         )
217 '
218
219 test_expect_success 'set core.splitIndex config variable to true' '
220         git config core.splitIndex true &&
221         : >three &&
222         git update-index --add three &&
223         git ls-files --stage >ls-files.actual &&
224         cat >ls-files.expect <<-EOF &&
225         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
226         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       three
227         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
228         EOF
229         test_cmp ls-files.expect ls-files.actual &&
230         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
231         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
232         cat >expect <<-EOF &&
233         $BASE
234         replacements:
235         deletions:
236         EOF
237         test_cmp expect actual
238 '
239
240 test_expect_success 'set core.splitIndex config variable to false' '
241         git config core.splitIndex false &&
242         git update-index --force-remove three &&
243         git ls-files --stage >ls-files.actual &&
244         cat >ls-files.expect <<-EOF &&
245         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
246         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
247         EOF
248         test_cmp ls-files.expect ls-files.actual &&
249         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
250         cat >expect <<-EOF &&
251         not a split index
252         EOF
253         test_cmp expect actual
254 '
255
256 test_expect_success 'set core.splitIndex config variable to true' '
257         git config core.splitIndex true &&
258         : >three &&
259         git update-index --add three &&
260         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
261         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
262         cat >expect <<-EOF &&
263         $BASE
264         replacements:
265         deletions:
266         EOF
267         test_cmp expect actual &&
268         : >four &&
269         git update-index --add four &&
270         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
271         cat >expect <<-EOF &&
272         $BASE
273         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       four
274         replacements:
275         deletions:
276         EOF
277         test_cmp expect actual
278 '
279
280 test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
281         git config --unset splitIndex.maxPercentChange &&
282         : >five &&
283         git update-index --add five &&
284         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
285         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
286         cat >expect <<-EOF &&
287         $BASE
288         replacements:
289         deletions:
290         EOF
291         test_cmp expect actual &&
292         : >six &&
293         git update-index --add six &&
294         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
295         cat >expect <<-EOF &&
296         $BASE
297         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       six
298         replacements:
299         deletions:
300         EOF
301         test_cmp expect actual
302 '
303
304 test_expect_success 'check splitIndex.maxPercentChange set to 0' '
305         git config splitIndex.maxPercentChange 0 &&
306         : >seven &&
307         git update-index --add seven &&
308         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
309         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
310         cat >expect <<-EOF &&
311         $BASE
312         replacements:
313         deletions:
314         EOF
315         test_cmp expect actual &&
316         : >eight &&
317         git update-index --add eight &&
318         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
319         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
320         cat >expect <<-EOF &&
321         $BASE
322         replacements:
323         deletions:
324         EOF
325         test_cmp expect actual
326 '
327
328 test_expect_success 'shared index files expire after 2 weeks by default' '
329         : >ten &&
330         git update-index --add ten &&
331         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
332         just_under_2_weeks_ago=$((5-14*86400)) &&
333         test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
334         : >eleven &&
335         git update-index --add eleven &&
336         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
337         just_over_2_weeks_ago=$((-1-14*86400)) &&
338         test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
339         : >twelve &&
340         git update-index --add twelve &&
341         test $(ls .git/sharedindex.* | wc -l) -le 2
342 '
343
344 test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
345         git config splitIndex.sharedIndexExpire "16.days.ago" &&
346         test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
347         : >thirteen &&
348         git update-index --add thirteen &&
349         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
350         just_over_16_days_ago=$((-1-16*86400)) &&
351         test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
352         : >fourteen &&
353         git update-index --add fourteen &&
354         test $(ls .git/sharedindex.* | wc -l) -le 2
355 '
356
357 test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
358         git config splitIndex.sharedIndexExpire never &&
359         just_10_years_ago=$((-365*10*86400)) &&
360         test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
361         : >fifteen &&
362         git update-index --add fifteen &&
363         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
364         git config splitIndex.sharedIndexExpire now &&
365         just_1_second_ago=-1 &&
366         test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
367         : >sixteen &&
368         git update-index --add sixteen &&
369         test $(ls .git/sharedindex.* | wc -l) -le 2
370 '
371
372 test_expect_success POSIXPERM 'same mode for index & split index' '
373         git init same-mode &&
374         (
375                 cd same-mode &&
376                 test_commit A &&
377                 test_modebits .git/index >index_mode &&
378                 test_must_fail git config core.sharedRepository &&
379                 git -c core.splitIndex=true status &&
380                 shared=$(ls .git/sharedindex.*) &&
381                 case "$shared" in
382                 *" "*)
383                         # we have more than one???
384                         false ;;
385                 *)
386                         test_modebits "$shared" >split_index_mode &&
387                         test_cmp index_mode split_index_mode ;;
388                 esac
389         )
390 '
391
392 while read -r mode modebits
393 do
394         test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
395                 # Remove existing shared index files
396                 git config core.splitIndex false &&
397                 git update-index --force-remove one &&
398                 rm -f .git/sharedindex.* &&
399                 # Create one new shared index file
400                 git config core.sharedrepository "$mode" &&
401                 git config core.splitIndex true &&
402                 : >one &&
403                 git update-index --add one &&
404                 echo "$modebits" >expect &&
405                 test_modebits .git/index >actual &&
406                 test_cmp expect actual &&
407                 shared=$(ls .git/sharedindex.*) &&
408                 case "$shared" in
409                 *" "*)
410                         # we have more than one???
411                         false ;;
412                 *)
413                         test_modebits "$shared" >actual &&
414                         test_cmp expect actual ;;
415                 esac
416         '
417 done <<\EOF
418 0666 -rw-rw-rw-
419 0642 -rw-r---w-
420 EOF
421
422 test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
423         test_create_repo ro &&
424         (
425                 cd ro &&
426                 test_commit initial &&
427                 git update-index --split-index &&
428                 test -f .git/sharedindex.*
429         ) &&
430         cp ro/.git/index new-index &&
431         test_when_finished "chmod u+w ro/.git" &&
432         chmod u-w ro/.git &&
433         GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
434         chmod u+w ro/.git &&
435         rm ro/.git/sharedindex.* &&
436         GIT_INDEX_FILE=new-index git ls-files >actual &&
437         echo initial.t >expected &&
438         test_cmp expected actual
439 '
440
441 test_expect_success 'writing split index with null sha1 does not write cache tree' '
442         git config core.splitIndex true &&
443         git config splitIndex.maxPercentChange 0 &&
444         git commit -m "commit" &&
445         {
446                 git ls-tree HEAD &&
447                 printf "160000 commit $ZERO_OID\\tbroken\\n"
448         } >broken-tree &&
449         echo "add broken entry" >msg &&
450
451         tree=$(git mktree <broken-tree) &&
452         test_tick &&
453         commit=$(git commit-tree $tree -p HEAD <msg) &&
454         git update-ref HEAD "$commit" &&
455         GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
456         test_might_fail test-tool dump-cache-tree >cache-tree.out &&
457         test_line_count = 0 cache-tree.out
458 '
459
460 test_done