]> git.ipfire.org Git - thirdparty/git.git/blame - t/t5000-tar-tree.sh
archive-tar: report filter start error only once
[thirdparty/git.git] / t / t5000-tar-tree.sh
CommitLineData
d3d49c3d
RS
1#!/bin/sh
2#
3# Copyright (C) 2005 Rene Scharfe
4#
5
925ceccf 6test_description='git archive and git get-tar-commit-id test
d3d49c3d 7
5b860406
RS
8This test covers the topics of file contents, commit date handling and
9commit id embedding:
d3d49c3d
RS
10
11 The contents of the repository is compared to the extracted tar
12 archive. The repository contains simple text files, symlinks and a
3dff5379 13 binary file (/bin/sh). Only paths shorter than 99 characters are
5b860406 14 used.
d3d49c3d 15
925ceccf 16 git archive applies the commit date to every file in the archive it
d3d49c3d
RS
17 creates. The test sets the commit date to a specific value and checks
18 if the tar archive contains that value.
19
925ceccf 20 When giving git archive a commit id (in contrast to a tree id) it
d3d49c3d 21 embeds this commit id into the tar archive as a comment. The test
5be60078 22 checks the ability of git get-tar-commit-id to figure it out from the
d3d49c3d
RS
23 tar file.
24
25'
26
8da0b02d 27TEST_CREATE_REPO_NO_TEMPLATE=1
d3d49c3d
RS
28. ./test-lib.sh
29
38c9c9b7 30SUBSTFORMAT=%H%n
8460b2fc 31
9bf1ac41
RS
32test_lazy_prereq TAR_NEEDS_PAX_FALLBACK '
33 (
34 mkdir pax &&
35 cd pax &&
36 "$TAR" xf "$TEST_DIRECTORY"/t5000/pax.tar &&
37 test -f PaxHeaders.1791/file
38 )
39'
40
96174145
JK
41test_lazy_prereq GZIP 'gzip --version'
42
9bf1ac41
RS
43get_pax_header() {
44 file=$1
45 header=$2=
46
47 while read len rest
48 do
49 if test "$len" = $(echo "$len $rest" | wc -c)
50 then
51 case "$rest" in
52 $header*)
53 echo "${rest#$header}"
54 ;;
55 esac
56 fi
57 done <"$file"
58}
59
deb9c8ed
RS
60check_tar() {
61 tarfile=$1.tar
62 listfile=$1.lst
63 dir=$1
64 dir_with_prefix=$dir/$2
65
66 test_expect_success ' extract tar archive' '
67 (mkdir $dir && cd $dir && "$TAR" xf -) <$tarfile
68 '
69
9bf1ac41
RS
70 test_expect_success TAR_NEEDS_PAX_FALLBACK ' interpret pax headers' '
71 (
72 cd $dir &&
73 for header in *.paxheader
74 do
75 data=${header%.paxheader}.data &&
d0b30a3d 76 if test -h $data || test -e $data
9bf1ac41
RS
77 then
78 path=$(get_pax_header $header path) &&
79 if test -n "$path"
80 then
d0fd9931 81 mv "$data" "$path" || exit 1
9bf1ac41
RS
82 fi
83 fi
84 done
85 )
86 '
87
deb9c8ed
RS
88 test_expect_success ' validate filenames' '
89 (cd ${dir_with_prefix}a && find .) | sort >$listfile &&
90 test_cmp a.lst $listfile
91 '
92
93 test_expect_success ' validate file contents' '
94 diff -r a ${dir_with_prefix}a
95 '
96}
97
2947a793
RS
98check_added() {
99 dir=$1
100 path_in_fs=$2
101 path_in_archive=$3
102
103 test_expect_success " validate extra file $path_in_archive" '
104 diff -r $path_in_fs $dir/$path_in_archive
105 '
106}
107
0b78a1b2 108test_expect_success 'setup' '
109 test_oid_cache <<-EOF
110 obj sha1:19f9c8273ec45a8938e6999cb59b3ff66739902a
111 obj sha256:3c666f798798601571f5cec0adb57ce4aba8546875e7693177e0535f34d2c49b
112 EOF
113'
114
9c8e7e96
HWN
115test_expect_success 'populate workdir' '
116 mkdir a &&
117 echo simple textfile >a/a &&
118 ten=0123456789 &&
119 hundred="$ten$ten$ten$ten$ten$ten$ten$ten$ten$ten" &&
120 echo long filename >"a/four$hundred" &&
121 mkdir a/bin &&
122 test-tool genrandom "frotz" 500000 >a/bin/sh &&
123 printf "A\$Format:%s\$O" "$SUBSTFORMAT" >a/substfile1 &&
124 printf "A not substituted O" >a/substfile2 &&
125 if test_have_prereq SYMLINKS
126 then
127 ln -s a a/l1
128 else
129 printf %s a >a/l1
130 fi &&
131 (
132 p=long_path_to_a_file &&
133 cd a &&
134 for depth in 1 2 3 4 5
135 do
136 mkdir $p &&
d0fd9931 137 cd $p || exit 1
9c8e7e96
HWN
138 done &&
139 echo text >file_with_long_path
140 ) &&
141 (cd a && find .) | sort >a.lst
142'
d3d49c3d 143
008d896d
RS
144test_expect_success \
145 'add ignored file' \
146 'echo ignore me >a/ignored &&
8da0b02d 147 mkdir .git/info &&
ad94657f 148 echo ignored export-ignore >.git/info/attributes'
008d896d 149
21711ca4
RS
150test_expect_success 'add files to repository' '
151 git add a &&
152 GIT_COMMITTER_DATE="2005-05-27 22:00" git commit -m initial
153'
d3d49c3d 154
c420df7b
RS
155test_expect_success 'setup export-subst' '
156 echo "substfile?" export-subst >>.git/info/attributes &&
157 git log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \
158 >a/substfile1
159'
160
9c8e7e96 161test_expect_success 'create bare clone' '
8da0b02d
ÆAB
162 git clone --template= --bare . bare.git &&
163 mkdir bare.git/info &&
9c8e7e96
HWN
164 cp .git/info/attributes bare.git/info/attributes
165'
ddff8563 166
9c8e7e96
HWN
167test_expect_success 'remove ignored file' '
168 rm a/ignored
169'
008d896d 170
9c8e7e96
HWN
171test_expect_success 'git archive' '
172 git archive HEAD >b.tar
173'
8ff21b1a 174
deb9c8ed
RS
175check_tar b
176
03d9bc56
RS
177test_expect_success 'git archive --prefix=prefix/' '
178 git archive --prefix=prefix/ HEAD >with_prefix.tar
179'
180
181check_tar with_prefix prefix/
182
183test_expect_success 'git-archive --prefix=olde-' '
184 git archive --prefix=olde- HEAD >with_olde-prefix.tar
185'
186
187check_tar with_olde-prefix olde-
188
2947a793
RS
189test_expect_success 'git archive --add-file' '
190 echo untracked >untracked &&
191 git archive --add-file=untracked HEAD >with_untracked.tar
192'
193
194check_tar with_untracked
195check_added with_untracked untracked untracked
196
197test_expect_success 'git archive --add-file twice' '
198 echo untracked >untracked &&
199 git archive --prefix=one/ --add-file=untracked \
200 --prefix=two/ --add-file=untracked \
201 --prefix= HEAD >with_untracked2.tar
202'
203
204check_tar with_untracked2
205check_added with_untracked2 untracked one/untracked
206check_added with_untracked2 untracked two/untracked
207
5544049d 208test_expect_success 'git archive on large files' '
9c8e7e96
HWN
209 test_config core.bigfilethreshold 1 &&
210 git archive HEAD >b3.tar &&
211 test_cmp_bin b.tar b3.tar
5544049d
NTND
212'
213
9c8e7e96
HWN
214test_expect_success 'git archive in a bare repo' '
215 git --git-dir bare.git archive HEAD >b3.tar
216'
ddff8563 217
9c8e7e96
HWN
218test_expect_success 'git archive vs. the same in a bare repo' '
219 test_cmp_bin b.tar b3.tar
220'
ddff8563 221
9c8e7e96
HWN
222test_expect_success 'git archive with --output' '
223 git archive --output=b4.tar HEAD &&
224 test_cmp_bin b.tar b4.tar
225'
aec0c1bb 226
9c8e7e96
HWN
227test_expect_success 'git archive --remote' '
228 git archive --remote=. HEAD >b5.tar &&
229 test_cmp_bin b.tar b5.tar
230'
48139269 231
eb0224c6
JH
232test_expect_success 'git archive --remote with configured remote' '
233 git config remote.foo.url . &&
234 (
235 cd a &&
236 git archive --remote=foo --output=../b5-nick.tar HEAD
237 ) &&
238 test_cmp_bin b.tar b5-nick.tar
239'
240
9c8e7e96
HWN
241test_expect_success 'validate file modification time' '
242 mkdir extract &&
243 "$TAR" xf b.tar -C extract a/a &&
244 test-tool chmtime --get extract/a/a >b.mtime &&
245 echo "1117231200" >expected.mtime &&
246 test_cmp expected.mtime b.mtime
247'
d3d49c3d 248
f1ed2247
HWN
249test_expect_success 'git get-tar-commit-id' '
250 git get-tar-commit-id <b.tar >actual &&
251 git rev-parse HEAD >expect &&
252 test_cmp expect actual
253'
d3d49c3d 254
fe12d8e8
RS
255test_expect_success 'git archive with --output, override inferred format' '
256 git archive --format=tar --output=d4.zip HEAD &&
b93e6e36 257 test_cmp_bin b.tar d4.zip
fe12d8e8
RS
258'
259
00436bf1
JS
260test_expect_success GZIP 'git archive with --output and --remote creates .tgz' '
261 git archive --output=d5.tgz --remote=. HEAD &&
262 gzip -d -c <d5.tgz >d5.tar &&
263 test_cmp_bin b.tar d5.tar
264'
265
eb0224c6
JH
266test_expect_success 'git archive --list outside of a git repo' '
267 nongit git archive --list
268'
269
270test_expect_success 'git archive --remote outside of a git repo' '
271 git archive HEAD >expect.tar &&
272 nongit git archive --remote="$PWD" HEAD >actual.tar &&
273 test_cmp_bin expect.tar actual.tar
274'
265d5280 275
ee27ca4a
JK
276test_expect_success 'clients cannot access unreachable commits' '
277 test_commit unreachable &&
f5efd519 278 sha1=$(git rev-parse HEAD) &&
ee27ca4a
JK
279 git reset --hard HEAD^ &&
280 git archive $sha1 >remote.tar &&
281 test_must_fail git archive --remote=. $sha1 >remote.tar
282'
283
7671b632
SG
284test_expect_success 'upload-archive can allow unreachable commits' '
285 test_commit unreachable1 &&
f5efd519 286 sha1=$(git rev-parse HEAD) &&
7671b632
SG
287 git reset --hard HEAD^ &&
288 git archive $sha1 >remote.tar &&
289 test_config uploadarchive.allowUnreachable true &&
290 git archive --remote=. $sha1 >remote.tar
291'
292
767cf457
JK
293test_expect_success 'setup tar filters' '
294 git config tar.tar.foo.command "tr ab ba" &&
7b97730b 295 git config tar.bar.command "tr ab ba" &&
785a0429
JK
296 git config tar.bar.remote true &&
297 git config tar.invalid baz
767cf457
JK
298'
299
300test_expect_success 'archive --list mentions user filter' '
301 git archive --list >output &&
302 grep "^tar\.foo\$" output &&
303 grep "^bar\$" output
304'
305
1bc01efe 306test_expect_success 'archive --list shows only enabled remote filters' '
767cf457 307 git archive --list --remote=. >output &&
7b97730b 308 ! grep "^tar\.foo\$" output &&
767cf457
JK
309 grep "^bar\$" output
310'
311
312test_expect_success 'invoke tar filter by format' '
313 git archive --format=tar.foo HEAD >config.tar.foo &&
314 tr ab ba <config.tar.foo >config.tar &&
b93e6e36 315 test_cmp_bin b.tar config.tar &&
767cf457
JK
316 git archive --format=bar HEAD >config.bar &&
317 tr ab ba <config.bar >config.tar &&
b93e6e36 318 test_cmp_bin b.tar config.tar
767cf457
JK
319'
320
321test_expect_success 'invoke tar filter by extension' '
322 git archive -o config-implicit.tar.foo HEAD &&
b93e6e36 323 test_cmp_bin config.tar.foo config-implicit.tar.foo &&
767cf457 324 git archive -o config-implicit.bar HEAD &&
b93e6e36 325 test_cmp_bin config.tar.foo config-implicit.bar
767cf457
JK
326'
327
328test_expect_success 'default output format remains tar' '
329 git archive -o config-implicit.baz HEAD &&
b93e6e36 330 test_cmp_bin b.tar config-implicit.baz
767cf457
JK
331'
332
333test_expect_success 'extension matching requires dot' '
334 git archive -o config-implicittar.foo HEAD &&
b93e6e36 335 test_cmp_bin b.tar config-implicittar.foo
767cf457
JK
336'
337
1bc01efe 338test_expect_success 'only enabled filters are available remotely' '
7b97730b
JK
339 test_must_fail git archive --remote=. --format=tar.foo HEAD \
340 >remote.tar.foo &&
341 git archive --remote=. --format=bar >remote.bar HEAD &&
b93e6e36 342 test_cmp_bin remote.bar config.bar
7b97730b
JK
343'
344
1e4ea950
RS
345test_expect_success 'invalid filter is reported only once' '
346 test_must_fail git -c tar.invalid.command= archive --format=invalid \
347 HEAD >out 2>err &&
348 test_must_be_empty out &&
349 test_line_count = 1 err
350'
351
4f4be00d 352test_expect_success 'git archive --format=tgz' '
0e804e09
JK
353 git archive --format=tgz HEAD >j.tgz
354'
355
4f4be00d 356test_expect_success 'git archive --format=tar.gz' '
0e804e09 357 git archive --format=tar.gz HEAD >j1.tar.gz &&
b93e6e36 358 test_cmp_bin j.tgz j1.tar.gz
0e804e09
JK
359'
360
4f4be00d 361test_expect_success 'infer tgz from .tgz filename' '
0e804e09 362 git archive --output=j2.tgz HEAD &&
b93e6e36 363 test_cmp_bin j.tgz j2.tgz
0e804e09
JK
364'
365
4f4be00d 366test_expect_success 'infer tgz from .tar.gz filename' '
0e804e09 367 git archive --output=j3.tar.gz HEAD &&
b93e6e36 368 test_cmp_bin j.tgz j3.tar.gz
0e804e09
JK
369'
370
96174145
JK
371test_expect_success GZIP 'extract tgz file' '
372 gzip -d -c <j.tgz >j.tar &&
b93e6e36 373 test_cmp_bin b.tar j.tar
0e804e09
JK
374'
375
4f4be00d 376test_expect_success 'remote tar.gz is allowed by default' '
7b97730b 377 git archive --remote=. --format=tar.gz HEAD >remote.tar.gz &&
b93e6e36 378 test_cmp_bin j.tgz remote.tar.gz
7b97730b
JK
379'
380
4f4be00d 381test_expect_success 'remote tar.gz can be disabled' '
7b97730b
JK
382 git config tar.tar.gz.remote false &&
383 test_must_fail git archive --remote=. --format=tar.gz HEAD \
384 >remote.tar.gz
385'
386
4f4be00d
RS
387test_expect_success GZIP 'git archive --format=tgz (external gzip)' '
388 test_config tar.tgz.command "gzip -cn" &&
389 git archive --format=tgz HEAD >external_gzip.tgz
76d76026
RS
390'
391
4f4be00d
RS
392test_expect_success GZIP 'git archive --format=tar.gz (external gzip)' '
393 test_config tar.tar.gz.command "gzip -cn" &&
394 git archive --format=tar.gz HEAD >external_gzip.tar.gz &&
395 test_cmp_bin external_gzip.tgz external_gzip.tar.gz
76d76026
RS
396'
397
4f4be00d
RS
398test_expect_success GZIP 'extract tgz file (external gzip)' '
399 gzip -d -c <external_gzip.tgz >external_gzip.tar &&
400 test_cmp_bin b.tar external_gzip.tar
76d76026
RS
401'
402
ed22b417
NTND
403test_expect_success 'archive and :(glob)' '
404 git archive -v HEAD -- ":(glob)**/sh" >/dev/null 2>actual &&
405 cat >expect <<EOF &&
406a/
407a/bin/
408a/bin/sh
409EOF
410 test_cmp expect actual
411'
412
413test_expect_success 'catch non-matching pathspec' '
414 test_must_fail git archive -v HEAD -- "*.abc" >/dev/null
415'
416
e51217e1
JK
417# Pull the size and date of each entry in a tarfile using the system tar.
418#
419# We'll pull out only the year from the date; that avoids any question of
420# timezones impacting the result (as long as we keep our test times away from a
421# year boundary; our reference times are all in August).
422#
423# The output of tar_info is expected to be "<size> <year>", both in decimal. It
424# ignores the return value of tar. We have to do this, because some of our test
425# input is only partial (the real data is 64GB in some cases).
426tar_info () {
427 "$TAR" tvf "$1" |
428 awk '{
429 split($4, date, "-")
430 print $3 " " date[1]
431 }'
432}
433
434# See if our system tar can handle a tar file with huge sizes and dates far in
435# the future, and that we can actually parse its output.
436#
437# The reference file was generated by GNU tar, and the magic time and size are
438# both octal 01000000000001, which overflows normal ustar fields.
439test_lazy_prereq TAR_HUGE '
440 echo "68719476737 4147" >expect &&
441 tar_info "$TEST_DIRECTORY"/t5000/huge-and-future.tar >actual &&
442 test_cmp expect actual
443'
444
29493589 445test_expect_success LONG_IS_64BIT 'set up repository with huge blob' '
0b78a1b2 446 obj=$(test_oid obj) &&
447 path=$(test_oid_to_path $obj) &&
448 mkdir -p .git/objects/$(dirname $path) &&
449 cp "$TEST_DIRECTORY"/t5000/huge-object .git/objects/$path &&
e51217e1
JK
450 rm -f .git/index &&
451 git update-index --add --cacheinfo 100644,$obj,huge &&
452 git commit -m huge
453'
454
455# We expect git to die with SIGPIPE here (otherwise we
456# would generate the whole 64GB).
29493589 457test_expect_success LONG_IS_64BIT 'generate tar with huge size' '
e51217e1
JK
458 {
459 git archive HEAD
460 echo $? >exit-code
461 } | test_copy_bytes 4096 >huge.tar &&
462 echo 141 >expect &&
463 test_cmp expect exit-code
464'
465
29493589 466test_expect_success TAR_HUGE,LONG_IS_64BIT 'system tar can read our huge size' '
e51217e1
JK
467 echo 68719476737 >expect &&
468 tar_info huge.tar | cut -d" " -f1 >actual &&
469 test_cmp expect actual
470'
471
f90fca63
AK
472test_expect_success TIME_IS_64BIT 'set up repository with far-future (2^34 - 1) commit' '
473 rm -f .git/index &&
474 echo foo >file &&
475 git add file &&
476 GIT_COMMITTER_DATE="@17179869183 +0000" \
477 git commit -m "tempori parendum"
478'
479
480test_expect_success TIME_IS_64BIT 'generate tar with far-future mtime' '
481 git archive HEAD >future.tar
482'
483
484test_expect_success TAR_HUGE,TIME_IS_64BIT,TIME_T_IS_64BIT 'system tar can read our future mtime' '
485 echo 2514 >expect &&
486 tar_info future.tar | cut -d" " -f2 >actual &&
487 test_cmp expect actual
488'
489
490test_expect_success TIME_IS_64BIT 'set up repository with far-far-future (2^36 + 1) commit' '
e51217e1
JK
491 rm -f .git/index &&
492 echo content >file &&
493 git add file &&
f90fca63 494 GIT_TEST_COMMIT_GRAPH=0 GIT_COMMITTER_DATE="@68719476737 +0000" \
e51217e1
JK
495 git commit -m "tempori parendum"
496'
497
f90fca63 498test_expect_success TIME_IS_64BIT 'generate tar with far-far-future mtime' '
e51217e1
JK
499 git archive HEAD >future.tar
500'
501
efac8ac8 502test_expect_success TAR_HUGE,TIME_IS_64BIT,TIME_T_IS_64BIT 'system tar can read our future mtime' '
e51217e1
JK
503 echo 4147 >expect &&
504 tar_info future.tar | cut -d" " -f2 >actual &&
505 test_cmp expect actual
506'
507
d3d49c3d 508test_done