]> git.ipfire.org Git - thirdparty/git.git/blame - t/t5000-tar-tree.sh
Merge branch 'jk/clone-allow-bare-and-o-together'
[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
4f4be00d 345test_expect_success 'git archive --format=tgz' '
0e804e09
JK
346 git archive --format=tgz HEAD >j.tgz
347'
348
4f4be00d 349test_expect_success 'git archive --format=tar.gz' '
0e804e09 350 git archive --format=tar.gz HEAD >j1.tar.gz &&
b93e6e36 351 test_cmp_bin j.tgz j1.tar.gz
0e804e09
JK
352'
353
4f4be00d 354test_expect_success 'infer tgz from .tgz filename' '
0e804e09 355 git archive --output=j2.tgz HEAD &&
b93e6e36 356 test_cmp_bin j.tgz j2.tgz
0e804e09
JK
357'
358
4f4be00d 359test_expect_success 'infer tgz from .tar.gz filename' '
0e804e09 360 git archive --output=j3.tar.gz HEAD &&
b93e6e36 361 test_cmp_bin j.tgz j3.tar.gz
0e804e09
JK
362'
363
96174145
JK
364test_expect_success GZIP 'extract tgz file' '
365 gzip -d -c <j.tgz >j.tar &&
b93e6e36 366 test_cmp_bin b.tar j.tar
0e804e09
JK
367'
368
4f4be00d 369test_expect_success 'remote tar.gz is allowed by default' '
7b97730b 370 git archive --remote=. --format=tar.gz HEAD >remote.tar.gz &&
b93e6e36 371 test_cmp_bin j.tgz remote.tar.gz
7b97730b
JK
372'
373
4f4be00d 374test_expect_success 'remote tar.gz can be disabled' '
7b97730b
JK
375 git config tar.tar.gz.remote false &&
376 test_must_fail git archive --remote=. --format=tar.gz HEAD \
377 >remote.tar.gz
378'
379
4f4be00d
RS
380test_expect_success GZIP 'git archive --format=tgz (external gzip)' '
381 test_config tar.tgz.command "gzip -cn" &&
382 git archive --format=tgz HEAD >external_gzip.tgz
76d76026
RS
383'
384
4f4be00d
RS
385test_expect_success GZIP 'git archive --format=tar.gz (external gzip)' '
386 test_config tar.tar.gz.command "gzip -cn" &&
387 git archive --format=tar.gz HEAD >external_gzip.tar.gz &&
388 test_cmp_bin external_gzip.tgz external_gzip.tar.gz
76d76026
RS
389'
390
4f4be00d
RS
391test_expect_success GZIP 'extract tgz file (external gzip)' '
392 gzip -d -c <external_gzip.tgz >external_gzip.tar &&
393 test_cmp_bin b.tar external_gzip.tar
76d76026
RS
394'
395
ed22b417
NTND
396test_expect_success 'archive and :(glob)' '
397 git archive -v HEAD -- ":(glob)**/sh" >/dev/null 2>actual &&
398 cat >expect <<EOF &&
399a/
400a/bin/
401a/bin/sh
402EOF
403 test_cmp expect actual
404'
405
406test_expect_success 'catch non-matching pathspec' '
407 test_must_fail git archive -v HEAD -- "*.abc" >/dev/null
408'
409
e51217e1
JK
410# Pull the size and date of each entry in a tarfile using the system tar.
411#
412# We'll pull out only the year from the date; that avoids any question of
413# timezones impacting the result (as long as we keep our test times away from a
414# year boundary; our reference times are all in August).
415#
416# The output of tar_info is expected to be "<size> <year>", both in decimal. It
417# ignores the return value of tar. We have to do this, because some of our test
418# input is only partial (the real data is 64GB in some cases).
419tar_info () {
420 "$TAR" tvf "$1" |
421 awk '{
422 split($4, date, "-")
423 print $3 " " date[1]
424 }'
425}
426
427# See if our system tar can handle a tar file with huge sizes and dates far in
428# the future, and that we can actually parse its output.
429#
430# The reference file was generated by GNU tar, and the magic time and size are
431# both octal 01000000000001, which overflows normal ustar fields.
432test_lazy_prereq TAR_HUGE '
433 echo "68719476737 4147" >expect &&
434 tar_info "$TEST_DIRECTORY"/t5000/huge-and-future.tar >actual &&
435 test_cmp expect actual
436'
437
29493589 438test_expect_success LONG_IS_64BIT 'set up repository with huge blob' '
0b78a1b2 439 obj=$(test_oid obj) &&
440 path=$(test_oid_to_path $obj) &&
441 mkdir -p .git/objects/$(dirname $path) &&
442 cp "$TEST_DIRECTORY"/t5000/huge-object .git/objects/$path &&
e51217e1
JK
443 rm -f .git/index &&
444 git update-index --add --cacheinfo 100644,$obj,huge &&
445 git commit -m huge
446'
447
448# We expect git to die with SIGPIPE here (otherwise we
449# would generate the whole 64GB).
29493589 450test_expect_success LONG_IS_64BIT 'generate tar with huge size' '
e51217e1
JK
451 {
452 git archive HEAD
453 echo $? >exit-code
454 } | test_copy_bytes 4096 >huge.tar &&
455 echo 141 >expect &&
456 test_cmp expect exit-code
457'
458
29493589 459test_expect_success TAR_HUGE,LONG_IS_64BIT 'system tar can read our huge size' '
e51217e1
JK
460 echo 68719476737 >expect &&
461 tar_info huge.tar | cut -d" " -f1 >actual &&
462 test_cmp expect actual
463'
464
f90fca63
AK
465test_expect_success TIME_IS_64BIT 'set up repository with far-future (2^34 - 1) commit' '
466 rm -f .git/index &&
467 echo foo >file &&
468 git add file &&
469 GIT_COMMITTER_DATE="@17179869183 +0000" \
470 git commit -m "tempori parendum"
471'
472
473test_expect_success TIME_IS_64BIT 'generate tar with far-future mtime' '
474 git archive HEAD >future.tar
475'
476
477test_expect_success TAR_HUGE,TIME_IS_64BIT,TIME_T_IS_64BIT 'system tar can read our future mtime' '
478 echo 2514 >expect &&
479 tar_info future.tar | cut -d" " -f2 >actual &&
480 test_cmp expect actual
481'
482
483test_expect_success TIME_IS_64BIT 'set up repository with far-far-future (2^36 + 1) commit' '
e51217e1
JK
484 rm -f .git/index &&
485 echo content >file &&
486 git add file &&
f90fca63 487 GIT_TEST_COMMIT_GRAPH=0 GIT_COMMITTER_DATE="@68719476737 +0000" \
e51217e1
JK
488 git commit -m "tempori parendum"
489'
490
f90fca63 491test_expect_success TIME_IS_64BIT 'generate tar with far-far-future mtime' '
e51217e1
JK
492 git archive HEAD >future.tar
493'
494
efac8ac8 495test_expect_success TAR_HUGE,TIME_IS_64BIT,TIME_T_IS_64BIT 'system tar can read our future mtime' '
e51217e1
JK
496 echo 4147 >expect &&
497 tar_info future.tar | cut -d" " -f2 >actual &&
498 test_cmp expect actual
499'
500
d3d49c3d 501test_done