Merge branch 'maint-1.6.4' into maint-1.6.5
[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     'rm -f .git/index*
16      perl -e "print \"a\" x 4096;" > a &&
17      perl -e "print \"b\" x 4096;" > b &&
18      perl -e "print \"c\" x 4096;" > c &&
19      git update-index --add a b c &&
20      cat c >d && echo foo >>d && git update-index --add d &&
21      tree=`git write-tree` &&
22      commit=`git commit-tree $tree </dev/null` && {
23          echo $tree &&
24          echo $commit &&
25          git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\)       .*/\\1/"
26      } >obj-list && {
27          git diff-tree --root -p $commit &&
28          while read object
29          do
30             t=`git cat-file -t $object` &&
31             git cat-file $t $object || return 1
32          done <obj-list
33      } >expect'
34
35 test_expect_success \
36     'pack without delta' \
37     'packname_1=$(git pack-objects --window=0 test-1 <obj-list)'
38
39 rm -fr .git2
40 mkdir .git2
41
42 test_expect_success \
43     'unpack without delta' \
44     "GIT_OBJECT_DIRECTORY=.git2/objects &&
45      export GIT_OBJECT_DIRECTORY &&
46      git init &&
47      git unpack-objects -n <test-1-${packname_1}.pack &&
48      git unpack-objects <test-1-${packname_1}.pack"
49
50 unset GIT_OBJECT_DIRECTORY
51 cd "$TRASH/.git2"
52
53 test_expect_success \
54     'check unpack without delta' \
55     '(cd ../.git && find objects -type f -print) |
56      while read path
57      do
58          cmp $path ../.git/$path || {
59              echo $path differs.
60              return 1
61          }
62      done'
63 cd "$TRASH"
64
65 test_expect_success \
66     'pack with REF_DELTA' \
67     'pwd &&
68      packname_2=$(git pack-objects test-2 <obj-list)'
69
70 rm -fr .git2
71 mkdir .git2
72
73 test_expect_success \
74     'unpack with REF_DELTA' \
75     'GIT_OBJECT_DIRECTORY=.git2/objects &&
76      export GIT_OBJECT_DIRECTORY &&
77      git init &&
78      git unpack-objects -n <test-2-${packname_2}.pack &&
79      git unpack-objects <test-2-${packname_2}.pack'
80
81 unset GIT_OBJECT_DIRECTORY
82 cd "$TRASH/.git2"
83 test_expect_success \
84     'check unpack with REF_DELTA' \
85     '(cd ../.git && find objects -type f -print) |
86      while read path
87      do
88          cmp $path ../.git/$path || {
89              echo $path differs.
90              return 1
91          }
92      done'
93 cd "$TRASH"
94
95 test_expect_success \
96     'pack with OFS_DELTA' \
97     'pwd &&
98      packname_3=$(git pack-objects --delta-base-offset test-3 <obj-list)'
99
100 rm -fr .git2
101 mkdir .git2
102
103 test_expect_success \
104     'unpack with OFS_DELTA' \
105     'GIT_OBJECT_DIRECTORY=.git2/objects &&
106      export GIT_OBJECT_DIRECTORY &&
107      git init &&
108      git unpack-objects -n <test-3-${packname_3}.pack &&
109      git unpack-objects <test-3-${packname_3}.pack'
110
111 unset GIT_OBJECT_DIRECTORY
112 cd "$TRASH/.git2"
113 test_expect_success \
114     'check unpack with OFS_DELTA' \
115     '(cd ../.git && find objects -type f -print) |
116      while read path
117      do
118          cmp $path ../.git/$path || {
119              echo $path differs.
120              return 1
121          }
122      done'
123 cd "$TRASH"
124
125 test_expect_success 'compare delta flavors' '
126         perl -e '\''
127                 defined($_ = -s $_) or die for @ARGV;
128                 exit 1 if $ARGV[0] <= $ARGV[1];
129         '\'' test-2-$packname_2.pack test-3-$packname_3.pack
130 '
131
132 rm -fr .git2
133 mkdir .git2
134
135 test_expect_success \
136     'use packed objects' \
137     'GIT_OBJECT_DIRECTORY=.git2/objects &&
138      export GIT_OBJECT_DIRECTORY &&
139      git init &&
140      cp test-1-${packname_1}.pack test-1-${packname_1}.idx .git2/objects/pack && {
141          git diff-tree --root -p $commit &&
142          while read object
143          do
144             t=`git cat-file -t $object` &&
145             git cat-file $t $object || return 1
146          done <obj-list
147     } >current &&
148     diff expect current'
149
150 test_expect_success \
151     'use packed deltified (REF_DELTA) objects' \
152     'GIT_OBJECT_DIRECTORY=.git2/objects &&
153      export GIT_OBJECT_DIRECTORY &&
154      rm -f .git2/objects/pack/test-* &&
155      cp test-2-${packname_2}.pack test-2-${packname_2}.idx .git2/objects/pack && {
156          git diff-tree --root -p $commit &&
157          while read object
158          do
159             t=`git cat-file -t $object` &&
160             git cat-file $t $object || return 1
161          done <obj-list
162     } >current &&
163     diff expect current'
164
165 test_expect_success \
166     'use packed deltified (OFS_DELTA) objects' \
167     'GIT_OBJECT_DIRECTORY=.git2/objects &&
168      export GIT_OBJECT_DIRECTORY &&
169      rm -f .git2/objects/pack/test-* &&
170      cp test-3-${packname_3}.pack test-3-${packname_3}.idx .git2/objects/pack && {
171          git diff-tree --root -p $commit &&
172          while read object
173          do
174             t=`git cat-file -t $object` &&
175             git cat-file $t $object || return 1
176          done <obj-list
177     } >current &&
178     diff expect current'
179
180 unset GIT_OBJECT_DIRECTORY
181
182 test_expect_success 'survive missing objects/pack directory' '
183         (
184                 rm -fr missing-pack &&
185                 mkdir missing-pack &&
186                 cd missing-pack &&
187                 git init &&
188                 GOP=.git/objects/pack
189                 rm -fr $GOP &&
190                 git index-pack --stdin --keep=test <../test-3-${packname_3}.pack &&
191                 test -f $GOP/pack-${packname_3}.pack &&
192                 test_cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack &&
193                 test -f $GOP/pack-${packname_3}.idx &&
194                 test_cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx &&
195                 test -f $GOP/pack-${packname_3}.keep
196         )
197 '
198
199 test_expect_success \
200     'verify pack' \
201     'git verify-pack    test-1-${packname_1}.idx \
202                         test-2-${packname_2}.idx \
203                         test-3-${packname_3}.idx'
204
205 test_expect_success \
206     'verify pack -v' \
207     'git verify-pack -v test-1-${packname_1}.idx \
208                         test-2-${packname_2}.idx \
209                         test-3-${packname_3}.idx'
210
211 test_expect_success \
212     'verify-pack catches mismatched .idx and .pack files' \
213     'cat test-1-${packname_1}.idx >test-3.idx &&
214      cat test-2-${packname_2}.pack >test-3.pack &&
215      if git verify-pack test-3.idx
216      then false
217      else :;
218      fi'
219
220 test_expect_success \
221     'verify-pack catches a corrupted pack signature' \
222     'cat test-1-${packname_1}.pack >test-3.pack &&
223      echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=2 &&
224      if git verify-pack test-3.idx
225      then false
226      else :;
227      fi'
228
229 test_expect_success \
230     'verify-pack catches a corrupted pack version' \
231     'cat test-1-${packname_1}.pack >test-3.pack &&
232      echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=7 &&
233      if git verify-pack test-3.idx
234      then false
235      else :;
236      fi'
237
238 test_expect_success \
239     'verify-pack catches a corrupted type/size of the 1st packed object data' \
240     'cat test-1-${packname_1}.pack >test-3.pack &&
241      echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=12 &&
242      if git verify-pack test-3.idx
243      then false
244      else :;
245      fi'
246
247 test_expect_success \
248     'verify-pack catches a corrupted sum of the index file itself' \
249     'l=`wc -c <test-3.idx` &&
250      l=`expr $l - 20` &&
251      cat test-1-${packname_1}.pack >test-3.pack &&
252      printf "%20s" "" | dd of=test-3.idx count=20 bs=1 conv=notrunc seek=$l &&
253      if git verify-pack test-3.pack
254      then false
255      else :;
256      fi'
257
258 test_expect_success \
259     'build pack index for an existing pack' \
260     'cat test-1-${packname_1}.pack >test-3.pack &&
261      git index-pack -o tmp.idx test-3.pack &&
262      cmp tmp.idx test-1-${packname_1}.idx &&
263
264      git index-pack test-3.pack &&
265      cmp test-3.idx test-1-${packname_1}.idx &&
266
267      cat test-2-${packname_2}.pack >test-3.pack &&
268      git index-pack -o tmp.idx test-2-${packname_2}.pack &&
269      cmp tmp.idx test-2-${packname_2}.idx &&
270
271      git index-pack test-3.pack &&
272      cmp test-3.idx test-2-${packname_2}.idx &&
273
274      cat test-3-${packname_3}.pack >test-3.pack &&
275      git index-pack -o tmp.idx test-3-${packname_3}.pack &&
276      cmp tmp.idx test-3-${packname_3}.idx &&
277
278      git index-pack test-3.pack &&
279      cmp test-3.idx test-3-${packname_3}.idx &&
280
281      :'
282
283 test_expect_success \
284     'fake a SHA1 hash collision' \
285     'test -f    .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67 &&
286      cp -f      .git/objects/9d/235ed07cd19811a6ceb342de82f190e49c9f68 \
287                 .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67'
288
289 test_expect_success \
290     'make sure index-pack detects the SHA1 collision' \
291     'test_must_fail git index-pack -o bad.idx test-3.pack 2>msg &&
292      grep "SHA1 COLLISION FOUND" msg'
293
294 test_expect_success \
295     'honor pack.packSizeLimit' \
296     'git config pack.packSizeLimit 200 &&
297      packname_4=$(git pack-objects test-4 <obj-list) &&
298      test 3 = $(ls test-4-*.pack | wc -l)'
299
300 test_expect_success 'unpacking with --strict' '
301
302         git config --unset pack.packsizelimit &&
303         for j in a b c d e f g
304         do
305                 for i in 0 1 2 3 4 5 6 7 8 9
306                 do
307                         o=$(echo $j$i | git hash-object -w --stdin) &&
308                         echo "100644 $o 0 $j$i"
309                 done
310         done >LIST &&
311         rm -f .git/index &&
312         git update-index --index-info <LIST &&
313         LIST=$(git write-tree) &&
314         rm -f .git/index &&
315         head -n 10 LIST | git update-index --index-info &&
316         LI=$(git write-tree) &&
317         rm -f .git/index &&
318         tail -n 10 LIST | git update-index --index-info &&
319         ST=$(git write-tree) &&
320         PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \
321                 git pack-objects test-5 ) &&
322         PACK6=$( (
323                         echo "$LIST"
324                         echo "$LI"
325                         echo "$ST"
326                  ) | git pack-objects test-6 ) &&
327         test_create_repo test-5 &&
328         (
329                 cd test-5 &&
330                 git unpack-objects --strict <../test-5-$PACK5.pack &&
331                 git ls-tree -r $LIST &&
332                 git ls-tree -r $LI &&
333                 git ls-tree -r $ST
334         ) &&
335         test_create_repo test-6 &&
336         (
337                 # tree-only into empty repo -- many unreachables
338                 cd test-6 &&
339                 test_must_fail git unpack-objects --strict <../test-6-$PACK6.pack
340         ) &&
341         (
342                 # already populated -- no unreachables
343                 cd test-5 &&
344                 git unpack-objects --strict <../test-6-$PACK6.pack
345         )
346 '
347
348 test_expect_success 'index-pack with --strict' '
349
350         for j in a b c d e f g
351         do
352                 for i in 0 1 2 3 4 5 6 7 8 9
353                 do
354                         o=$(echo $j$i | git hash-object -w --stdin) &&
355                         echo "100644 $o 0 $j$i"
356                 done
357         done >LIST &&
358         rm -f .git/index &&
359         git update-index --index-info <LIST &&
360         LIST=$(git write-tree) &&
361         rm -f .git/index &&
362         head -n 10 LIST | git update-index --index-info &&
363         LI=$(git write-tree) &&
364         rm -f .git/index &&
365         tail -n 10 LIST | git update-index --index-info &&
366         ST=$(git write-tree) &&
367         PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \
368                 git pack-objects test-5 ) &&
369         PACK6=$( (
370                         echo "$LIST"
371                         echo "$LI"
372                         echo "$ST"
373                  ) | git pack-objects test-6 ) &&
374         test_create_repo test-7 &&
375         (
376                 cd test-7 &&
377                 git index-pack --strict --stdin <../test-5-$PACK5.pack &&
378                 git ls-tree -r $LIST &&
379                 git ls-tree -r $LI &&
380                 git ls-tree -r $ST
381         ) &&
382         test_create_repo test-8 &&
383         (
384                 # tree-only into empty repo -- many unreachables
385                 cd test-8 &&
386                 test_must_fail git index-pack --strict --stdin <../test-6-$PACK6.pack
387         ) &&
388         (
389                 # already populated -- no unreachables
390                 cd test-7 &&
391                 git index-pack --strict --stdin <../test-6-$PACK6.pack
392         )
393 '
394
395 test_expect_success 'tolerate absurdly small packsizelimit' '
396         git config pack.packSizeLimit 2 &&
397         packname_9=$(git pack-objects test-9 <obj-list) &&
398         test $(wc -l <obj-list) = $(ls test-9-*.pack | wc -l)
399 '
400
401 test_done