Imported Upstream version 2.28.0
[platform/upstream/git.git] / t / t5300-pack-object.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5
6 test_description='git pack-object
7
8 '
9 . ./test-lib.sh
10
11 TRASH=$(pwd)
12
13 test_expect_success \
14     'setup' \
15     'test_oid_init &&
16      rm -f .git/index* &&
17      perl -e "print \"a\" x 4096;" > a &&
18      perl -e "print \"b\" x 4096;" > b &&
19      perl -e "print \"c\" x 4096;" > c &&
20      test-tool genrandom "seed a" 2097152 > a_big &&
21      test-tool genrandom "seed b" 2097152 > b_big &&
22      git update-index --add a a_big b b_big c &&
23      cat c >d && echo foo >>d && git update-index --add d &&
24      tree=$(git write-tree) &&
25      commit=$(git commit-tree $tree </dev/null) && {
26          echo $tree &&
27          echo $commit &&
28          git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\)       .*/\\1/"
29      } >obj-list && {
30          git diff-tree --root -p $commit &&
31          while read object
32          do
33             t=$(git cat-file -t $object) &&
34             git cat-file $t $object || return 1
35          done <obj-list
36      } >expect'
37
38 test_expect_success \
39     'pack without delta' \
40     'packname_1=$(git pack-objects --window=0 test-1 <obj-list)'
41
42 test_expect_success \
43     'pack-objects with bogus arguments' \
44     'test_must_fail git pack-objects --window=0 test-1 blah blah <obj-list'
45
46 rm -fr .git2
47 mkdir .git2
48
49 test_expect_success \
50     'unpack without delta' \
51     "GIT_OBJECT_DIRECTORY=.git2/objects &&
52      export GIT_OBJECT_DIRECTORY &&
53      git init &&
54      git unpack-objects -n <test-1-${packname_1}.pack &&
55      git unpack-objects <test-1-${packname_1}.pack"
56
57 unset GIT_OBJECT_DIRECTORY
58 cd "$TRASH/.git2"
59
60 test_expect_success \
61     'check unpack without delta' \
62     '(cd ../.git && find objects -type f -print) |
63      while read path
64      do
65          cmp $path ../.git/$path || {
66              echo $path differs.
67              return 1
68          }
69      done'
70 cd "$TRASH"
71
72 test_expect_success \
73     'pack with REF_DELTA' \
74     'pwd &&
75      packname_2=$(git pack-objects test-2 <obj-list)'
76
77 rm -fr .git2
78 mkdir .git2
79
80 test_expect_success \
81     'unpack with REF_DELTA' \
82     'GIT_OBJECT_DIRECTORY=.git2/objects &&
83      export GIT_OBJECT_DIRECTORY &&
84      git init &&
85      git unpack-objects -n <test-2-${packname_2}.pack &&
86      git unpack-objects <test-2-${packname_2}.pack'
87
88 unset GIT_OBJECT_DIRECTORY
89 cd "$TRASH/.git2"
90 test_expect_success \
91     'check unpack with REF_DELTA' \
92     '(cd ../.git && find objects -type f -print) |
93      while read path
94      do
95          cmp $path ../.git/$path || {
96              echo $path differs.
97              return 1
98          }
99      done'
100 cd "$TRASH"
101
102 test_expect_success \
103     'pack with OFS_DELTA' \
104     'pwd &&
105      packname_3=$(git pack-objects --delta-base-offset test-3 <obj-list)'
106
107 rm -fr .git2
108 mkdir .git2
109
110 test_expect_success \
111     'unpack with OFS_DELTA' \
112     'GIT_OBJECT_DIRECTORY=.git2/objects &&
113      export GIT_OBJECT_DIRECTORY &&
114      git init &&
115      git unpack-objects -n <test-3-${packname_3}.pack &&
116      git unpack-objects <test-3-${packname_3}.pack'
117
118 unset GIT_OBJECT_DIRECTORY
119 cd "$TRASH/.git2"
120 test_expect_success \
121     'check unpack with OFS_DELTA' \
122     '(cd ../.git && find objects -type f -print) |
123      while read path
124      do
125          cmp $path ../.git/$path || {
126              echo $path differs.
127              return 1
128          }
129      done'
130 cd "$TRASH"
131
132 test_expect_success 'compare delta flavors' '
133         perl -e '\''
134                 defined($_ = -s $_) or die for @ARGV;
135                 exit 1 if $ARGV[0] <= $ARGV[1];
136         '\'' test-2-$packname_2.pack test-3-$packname_3.pack
137 '
138
139 rm -fr .git2
140 mkdir .git2
141
142 test_expect_success \
143     'use packed objects' \
144     'GIT_OBJECT_DIRECTORY=.git2/objects &&
145      export GIT_OBJECT_DIRECTORY &&
146      git init &&
147      cp test-1-${packname_1}.pack test-1-${packname_1}.idx .git2/objects/pack && {
148          git diff-tree --root -p $commit &&
149          while read object
150          do
151             t=$(git cat-file -t $object) &&
152             git cat-file $t $object || return 1
153          done <obj-list
154     } >current &&
155     cmp expect current'
156
157 test_expect_success \
158     'use packed deltified (REF_DELTA) objects' \
159     'GIT_OBJECT_DIRECTORY=.git2/objects &&
160      export GIT_OBJECT_DIRECTORY &&
161      rm -f .git2/objects/pack/test-* &&
162      cp test-2-${packname_2}.pack test-2-${packname_2}.idx .git2/objects/pack && {
163          git diff-tree --root -p $commit &&
164          while read object
165          do
166             t=$(git cat-file -t $object) &&
167             git cat-file $t $object || return 1
168          done <obj-list
169     } >current &&
170     cmp expect current'
171
172 test_expect_success \
173     'use packed deltified (OFS_DELTA) objects' \
174     'GIT_OBJECT_DIRECTORY=.git2/objects &&
175      export GIT_OBJECT_DIRECTORY &&
176      rm -f .git2/objects/pack/test-* &&
177      cp test-3-${packname_3}.pack test-3-${packname_3}.idx .git2/objects/pack && {
178          git diff-tree --root -p $commit &&
179          while read object
180          do
181             t=$(git cat-file -t $object) &&
182             git cat-file $t $object || return 1
183          done <obj-list
184     } >current &&
185     cmp expect current'
186
187 unset GIT_OBJECT_DIRECTORY
188
189 test_expect_success 'survive missing objects/pack directory' '
190         (
191                 rm -fr missing-pack &&
192                 mkdir missing-pack &&
193                 cd missing-pack &&
194                 git init &&
195                 GOP=.git/objects/pack &&
196                 rm -fr $GOP &&
197                 git index-pack --stdin --keep=test <../test-3-${packname_3}.pack &&
198                 test -f $GOP/pack-${packname_3}.pack &&
199                 cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack &&
200                 test -f $GOP/pack-${packname_3}.idx &&
201                 cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx &&
202                 test -f $GOP/pack-${packname_3}.keep
203         )
204 '
205
206 test_expect_success \
207     'verify pack' \
208     'git verify-pack    test-1-${packname_1}.idx \
209                         test-2-${packname_2}.idx \
210                         test-3-${packname_3}.idx'
211
212 test_expect_success \
213     'verify pack -v' \
214     'git verify-pack -v test-1-${packname_1}.idx \
215                         test-2-${packname_2}.idx \
216                         test-3-${packname_3}.idx'
217
218 test_expect_success \
219     'verify-pack catches mismatched .idx and .pack files' \
220     'cat test-1-${packname_1}.idx >test-3.idx &&
221      cat test-2-${packname_2}.pack >test-3.pack &&
222      if git verify-pack test-3.idx
223      then false
224      else :;
225      fi'
226
227 test_expect_success \
228     'verify-pack catches a corrupted pack signature' \
229     'cat test-1-${packname_1}.pack >test-3.pack &&
230      echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=2 &&
231      if git verify-pack test-3.idx
232      then false
233      else :;
234      fi'
235
236 test_expect_success \
237     'verify-pack catches a corrupted pack version' \
238     'cat test-1-${packname_1}.pack >test-3.pack &&
239      echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=7 &&
240      if git verify-pack test-3.idx
241      then false
242      else :;
243      fi'
244
245 test_expect_success \
246     'verify-pack catches a corrupted type/size of the 1st packed object data' \
247     'cat test-1-${packname_1}.pack >test-3.pack &&
248      echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=12 &&
249      if git verify-pack test-3.idx
250      then false
251      else :;
252      fi'
253
254 test_expect_success \
255     'verify-pack catches a corrupted sum of the index file itself' \
256     'l=$(wc -c <test-3.idx) &&
257      l=$(expr $l - 20) &&
258      cat test-1-${packname_1}.pack >test-3.pack &&
259      printf "%20s" "" | dd of=test-3.idx count=20 bs=1 conv=notrunc seek=$l &&
260      if git verify-pack test-3.pack
261      then false
262      else :;
263      fi'
264
265 test_expect_success \
266     'build pack index for an existing pack' \
267     'cat test-1-${packname_1}.pack >test-3.pack &&
268      git index-pack -o tmp.idx test-3.pack &&
269      cmp tmp.idx test-1-${packname_1}.idx &&
270
271      git index-pack test-3.pack &&
272      cmp test-3.idx test-1-${packname_1}.idx &&
273
274      cat test-2-${packname_2}.pack >test-3.pack &&
275      git index-pack -o tmp.idx test-2-${packname_2}.pack &&
276      cmp tmp.idx test-2-${packname_2}.idx &&
277
278      git index-pack test-3.pack &&
279      cmp test-3.idx test-2-${packname_2}.idx &&
280
281      cat test-3-${packname_3}.pack >test-3.pack &&
282      git index-pack -o tmp.idx test-3-${packname_3}.pack &&
283      cmp tmp.idx test-3-${packname_3}.idx &&
284
285      git index-pack test-3.pack &&
286      cmp test-3.idx test-3-${packname_3}.idx &&
287
288      cat test-1-${packname_1}.pack >test-4.pack &&
289      rm -f test-4.keep &&
290      git index-pack --keep=why test-4.pack &&
291      cmp test-1-${packname_1}.idx test-4.idx &&
292      test -f test-4.keep &&
293
294      :'
295
296 test_expect_success 'unpacking with --strict' '
297
298         for j in a b c d e f g
299         do
300                 for i in 0 1 2 3 4 5 6 7 8 9
301                 do
302                         o=$(echo $j$i | git hash-object -w --stdin) &&
303                         echo "100644 $o 0 $j$i"
304                 done
305         done >LIST &&
306         rm -f .git/index &&
307         git update-index --index-info <LIST &&
308         LIST=$(git write-tree) &&
309         rm -f .git/index &&
310         head -n 10 LIST | git update-index --index-info &&
311         LI=$(git write-tree) &&
312         rm -f .git/index &&
313         tail -n 10 LIST | git update-index --index-info &&
314         ST=$(git write-tree) &&
315         git rev-list --objects "$LIST" "$LI" "$ST" >actual &&
316         PACK5=$( git pack-objects test-5 <actual ) &&
317         PACK6=$( (
318                         echo "$LIST"
319                         echo "$LI"
320                         echo "$ST"
321                  ) | git pack-objects test-6 ) &&
322         test_create_repo test-5 &&
323         (
324                 cd test-5 &&
325                 git unpack-objects --strict <../test-5-$PACK5.pack &&
326                 git ls-tree -r $LIST &&
327                 git ls-tree -r $LI &&
328                 git ls-tree -r $ST
329         ) &&
330         test_create_repo test-6 &&
331         (
332                 # tree-only into empty repo -- many unreachables
333                 cd test-6 &&
334                 test_must_fail git unpack-objects --strict <../test-6-$PACK6.pack
335         ) &&
336         (
337                 # already populated -- no unreachables
338                 cd test-5 &&
339                 git unpack-objects --strict <../test-6-$PACK6.pack
340         )
341 '
342
343 test_expect_success 'index-pack with --strict' '
344
345         for j in a b c d e f g
346         do
347                 for i in 0 1 2 3 4 5 6 7 8 9
348                 do
349                         o=$(echo $j$i | git hash-object -w --stdin) &&
350                         echo "100644 $o 0 $j$i"
351                 done
352         done >LIST &&
353         rm -f .git/index &&
354         git update-index --index-info <LIST &&
355         LIST=$(git write-tree) &&
356         rm -f .git/index &&
357         head -n 10 LIST | git update-index --index-info &&
358         LI=$(git write-tree) &&
359         rm -f .git/index &&
360         tail -n 10 LIST | git update-index --index-info &&
361         ST=$(git write-tree) &&
362         git rev-list --objects "$LIST" "$LI" "$ST" >actual &&
363         PACK5=$( git pack-objects test-5 <actual ) &&
364         PACK6=$( (
365                         echo "$LIST"
366                         echo "$LI"
367                         echo "$ST"
368                  ) | git pack-objects test-6 ) &&
369         test_create_repo test-7 &&
370         (
371                 cd test-7 &&
372                 git index-pack --strict --stdin <../test-5-$PACK5.pack &&
373                 git ls-tree -r $LIST &&
374                 git ls-tree -r $LI &&
375                 git ls-tree -r $ST
376         ) &&
377         test_create_repo test-8 &&
378         (
379                 # tree-only into empty repo -- many unreachables
380                 cd test-8 &&
381                 test_must_fail git index-pack --strict --stdin <../test-6-$PACK6.pack
382         ) &&
383         (
384                 # already populated -- no unreachables
385                 cd test-7 &&
386                 git index-pack --strict --stdin <../test-6-$PACK6.pack
387         )
388 '
389
390 test_expect_success 'honor pack.packSizeLimit' '
391         git config pack.packSizeLimit 3m &&
392         packname_10=$(git pack-objects test-10 <obj-list) &&
393         test 2 = $(ls test-10-*.pack | wc -l)
394 '
395
396 test_expect_success 'verify resulting packs' '
397         git verify-pack test-10-*.pack
398 '
399
400 test_expect_success 'tolerate packsizelimit smaller than biggest object' '
401         git config pack.packSizeLimit 1 &&
402         packname_11=$(git pack-objects test-11 <obj-list) &&
403         test 5 = $(ls test-11-*.pack | wc -l)
404 '
405
406 test_expect_success 'verify resulting packs' '
407         git verify-pack test-11-*.pack
408 '
409
410 test_expect_success 'set up pack for non-repo tests' '
411         # make sure we have a pack with no matching index file
412         cp test-1-*.pack foo.pack
413 '
414
415 test_expect_success 'index-pack --stdin complains of non-repo' '
416         nongit test_must_fail git index-pack --object-format=$(test_oid algo) --stdin <foo.pack &&
417         test_path_is_missing non-repo/.git
418 '
419
420 test_expect_success 'index-pack <pack> works in non-repo' '
421         nongit git index-pack --object-format=$(test_oid algo) ../foo.pack &&
422         test_path_is_file foo.idx
423 '
424
425 test_expect_success 'index-pack --strict <pack> works in non-repo' '
426         rm -f foo.idx &&
427         nongit git index-pack --strict --object-format=$(test_oid algo) ../foo.pack &&
428         test_path_is_file foo.idx
429 '
430
431 test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'index-pack --threads=N or pack.threads=N warns when no pthreads' '
432         test_must_fail git index-pack --threads=2 2>err &&
433         grep ^warning: err >warnings &&
434         test_line_count = 1 warnings &&
435         grep -F "no threads support, ignoring --threads=2" err &&
436
437         test_must_fail git -c pack.threads=2 index-pack 2>err &&
438         grep ^warning: err >warnings &&
439         test_line_count = 1 warnings &&
440         grep -F "no threads support, ignoring pack.threads" err &&
441
442         test_must_fail git -c pack.threads=2 index-pack --threads=4 2>err &&
443         grep ^warning: err >warnings &&
444         test_line_count = 2 warnings &&
445         grep -F "no threads support, ignoring --threads=4" err &&
446         grep -F "no threads support, ignoring pack.threads" err
447 '
448
449 test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'pack-objects --threads=N or pack.threads=N warns when no pthreads' '
450         git pack-objects --threads=2 --stdout --all </dev/null >/dev/null 2>err &&
451         grep ^warning: err >warnings &&
452         test_line_count = 1 warnings &&
453         grep -F "no threads support, ignoring --threads" err &&
454
455         git -c pack.threads=2 pack-objects --stdout --all </dev/null >/dev/null 2>err &&
456         grep ^warning: err >warnings &&
457         test_line_count = 1 warnings &&
458         grep -F "no threads support, ignoring pack.threads" err &&
459
460         git -c pack.threads=2 pack-objects --threads=4 --stdout --all </dev/null >/dev/null 2>err &&
461         grep ^warning: err >warnings &&
462         test_line_count = 2 warnings &&
463         grep -F "no threads support, ignoring --threads" err &&
464         grep -F "no threads support, ignoring pack.threads" err
465 '
466
467 test_expect_success 'pack-objects in too-many-packs mode' '
468         GIT_TEST_FULL_IN_PACK_ARRAY=1 git repack -ad &&
469         git fsck
470 '
471
472 test_expect_success 'setup: fake a SHA1 hash collision' '
473         git init corrupt &&
474         (
475                 cd corrupt &&
476                 long_a=$(git hash-object -w ../a | sed -e "s!^..!&/!") &&
477                 long_b=$(git hash-object -w ../b | sed -e "s!^..!&/!") &&
478                 test -f .git/objects/$long_b &&
479                 cp -f   .git/objects/$long_a \
480                         .git/objects/$long_b
481         )
482 '
483
484 test_expect_success 'make sure index-pack detects the SHA1 collision' '
485         (
486                 cd corrupt &&
487                 test_must_fail git index-pack -o ../bad.idx ../test-3.pack 2>msg &&
488                 test_i18ngrep "SHA1 COLLISION FOUND" msg
489         )
490 '
491
492 test_expect_success 'make sure index-pack detects the SHA1 collision (large blobs)' '
493         (
494                 cd corrupt &&
495                 test_must_fail git -c core.bigfilethreshold=1 index-pack -o ../bad.idx ../test-3.pack 2>msg &&
496                 test_i18ngrep "SHA1 COLLISION FOUND" msg
497         )
498 '
499
500 test_done