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