1#!/bin/sh
2#
3# Copyright (C) 2005 Rene Scharfe
4#
5
6test_description='git archive and git get-tar-commit-id test
7
8This test covers the topics of file contents, commit date handling and
9commit id embedding:
10
11 The contents of the repository is compared to the extracted tar
12 archive. The repository contains simple text files, symlinks and a
13 binary file (/bin/sh). Only paths shorter than 99 characters are
14 used.
15
16 git archive applies the commit date to every file in the archive it
17 creates. The test sets the commit date to a specific value and checks
18 if the tar archive contains that value.
19
20 When giving git archive a commit id (in contrast to a tree id) it
21 embeds this commit id into the tar archive as a comment. The test
22 checks the ability of git get-tar-commit-id to figure it out from the
23 tar file.
24
25'
26
27. ./test-lib.sh
28
29SUBSTFORMAT=%H%n
30
31test_lazy_prereq TAR_NEEDS_PAX_FALLBACK '
32 (
33 mkdir pax &&
34 cd pax &&
35 "$TAR" xf "$TEST_DIRECTORY"/t5000/pax.tar &&
36 test -f PaxHeaders.1791/file
37 )
38'
39
40test_lazy_prereq GZIP 'gzip --version'
41
42get_pax_header() {
43 file=$1
44 header=$2=
45
46 while read len rest
47 do
48 if test "$len" = $(echo "$len $rest" | wc -c)
49 then
50 case "$rest" in
51 $header*)
52 echo "${rest#$header}"
53 ;;
54 esac
55 fi
56 done <"$file"
57}
58
59check_tar() {
60 tarfile=$1.tar
61 listfile=$1.lst
62 dir=$1
63 dir_with_prefix=$dir/$2
64
65 test_expect_success ' extract tar archive' '
66 (mkdir $dir && cd $dir && "$TAR" xf -) <$tarfile
67 '
68
69 test_expect_success TAR_NEEDS_PAX_FALLBACK ' interpret pax headers' '
70 (
71 cd $dir &&
72 for header in *.paxheader
73 do
74 data=${header%.paxheader}.data &&
75 if test -h $data -o -e $data
76 then
77 path=$(get_pax_header $header path) &&
78 if test -n "$path"
79 then
80 mv "$data" "$path"
81 fi
82 fi
83 done
84 )
85 '
86
87 test_expect_success ' validate filenames' '
88 (cd ${dir_with_prefix}a && find .) | sort >$listfile &&
89 test_cmp a.lst $listfile
90 '
91
92 test_expect_success ' validate file contents' '
93 diff -r a ${dir_with_prefix}a
94 '
95}
96
97test_expect_success \
98 'populate workdir' \
99 'mkdir a &&
100 echo simple textfile >a/a &&
101 ten=0123456789 && hundred=$ten$ten$ten$ten$ten$ten$ten$ten$ten$ten &&
102 echo long filename >a/four$hundred &&
103 mkdir a/bin &&
104 cp /bin/sh a/bin &&
105 printf "A\$Format:%s\$O" "$SUBSTFORMAT" >a/substfile1 &&
106 printf "A not substituted O" >a/substfile2 &&
107 if test_have_prereq SYMLINKS; then
108 ln -s a a/l1
109 else
110 printf %s a > a/l1
111 fi &&
112 (p=long_path_to_a_file && cd a &&
113 for depth in 1 2 3 4 5; do mkdir $p && cd $p; done &&
114 echo text >file_with_long_path) &&
115 (cd a && find .) | sort >a.lst'
116
117test_expect_success \
118 'add ignored file' \
119 'echo ignore me >a/ignored &&
120 echo ignored export-ignore >.git/info/attributes'
121
122test_expect_success \
123 'add files to repository' \
124 'find a -type f | xargs git update-index --add &&
125 find a -type l | xargs git update-index --add &&
126 treeid=$(git write-tree) &&
127 echo $treeid >treeid &&
128 git update-ref HEAD $(TZ=GMT GIT_COMMITTER_DATE="2005-05-27 22:00:00" \
129 git commit-tree $treeid </dev/null)'
130
131test_expect_success 'setup export-subst' '
132 echo "substfile?" export-subst >>.git/info/attributes &&
133 git log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \
134 >a/substfile1
135'
136
137test_expect_success \
138 'create bare clone' \
139 'git clone --bare . bare.git &&
140 cp .git/info/attributes bare.git/info/attributes'
141
142test_expect_success \
143 'remove ignored file' \
144 'rm a/ignored'
145
146test_expect_success \
147 'git archive' \
148 'git archive HEAD >b.tar'
149
150check_tar b
151
152test_expect_success 'git archive --prefix=prefix/' '
153 git archive --prefix=prefix/ HEAD >with_prefix.tar
154'
155
156check_tar with_prefix prefix/
157
158test_expect_success 'git-archive --prefix=olde-' '
159 git archive --prefix=olde- HEAD >with_olde-prefix.tar
160'
161
162check_tar with_olde-prefix olde-
163
164test_expect_success 'git archive on large files' '
165 test_config core.bigfilethreshold 1 &&
166 git archive HEAD >b3.tar &&
167 test_cmp_bin b.tar b3.tar
168'
169
170test_expect_success \
171 'git archive in a bare repo' \
172 '(cd bare.git && git archive HEAD) >b3.tar'
173
174test_expect_success \
175 'git archive vs. the same in a bare repo' \
176 'test_cmp_bin b.tar b3.tar'
177
178test_expect_success 'git archive with --output' \
179 'git archive --output=b4.tar HEAD &&
180 test_cmp_bin b.tar b4.tar'
181
182test_expect_success 'git archive --remote' \
183 'git archive --remote=. HEAD >b5.tar &&
184 test_cmp_bin b.tar b5.tar'
185
186test_expect_success \
187 'validate file modification time' \
188 'mkdir extract &&
189 "$TAR" xf b.tar -C extract a/a &&
190 test-chmtime -v +0 extract/a/a |cut -f 1 >b.mtime &&
191 echo "1117231200" >expected.mtime &&
192 test_cmp expected.mtime b.mtime'
193
194test_expect_success \
195 'git get-tar-commit-id' \
196 'git get-tar-commit-id <b.tar >b.commitid &&
197 test_cmp .git/$(git symbolic-ref HEAD) b.commitid'
198
199test_expect_success 'git archive with --output, override inferred format' '
200 git archive --format=tar --output=d4.zip HEAD &&
201 test_cmp_bin b.tar d4.zip
202'
203
204test_expect_success \
205 'git archive --list outside of a git repo' \
206 'GIT_DIR=some/non-existing/directory git archive --list'
207
208test_expect_success 'clients cannot access unreachable commits' '
209 test_commit unreachable &&
210 sha1=$(git rev-parse HEAD) &&
211 git reset --hard HEAD^ &&
212 git archive $sha1 >remote.tar &&
213 test_must_fail git archive --remote=. $sha1 >remote.tar
214'
215
216test_expect_success 'upload-archive can allow unreachable commits' '
217 test_commit unreachable1 &&
218 sha1=$(git rev-parse HEAD) &&
219 git reset --hard HEAD^ &&
220 git archive $sha1 >remote.tar &&
221 test_config uploadarchive.allowUnreachable true &&
222 git archive --remote=. $sha1 >remote.tar
223'
224
225test_expect_success 'setup tar filters' '
226 git config tar.tar.foo.command "tr ab ba" &&
227 git config tar.bar.command "tr ab ba" &&
228 git config tar.bar.remote true &&
229 git config tar.invalid baz
230'
231
232test_expect_success 'archive --list mentions user filter' '
233 git archive --list >output &&
234 grep "^tar\.foo\$" output &&
235 grep "^bar\$" output
236'
237
238test_expect_success 'archive --list shows only enabled remote filters' '
239 git archive --list --remote=. >output &&
240 ! grep "^tar\.foo\$" output &&
241 grep "^bar\$" output
242'
243
244test_expect_success 'invoke tar filter by format' '
245 git archive --format=tar.foo HEAD >config.tar.foo &&
246 tr ab ba <config.tar.foo >config.tar &&
247 test_cmp_bin b.tar config.tar &&
248 git archive --format=bar HEAD >config.bar &&
249 tr ab ba <config.bar >config.tar &&
250 test_cmp_bin b.tar config.tar
251'
252
253test_expect_success 'invoke tar filter by extension' '
254 git archive -o config-implicit.tar.foo HEAD &&
255 test_cmp_bin config.tar.foo config-implicit.tar.foo &&
256 git archive -o config-implicit.bar HEAD &&
257 test_cmp_bin config.tar.foo config-implicit.bar
258'
259
260test_expect_success 'default output format remains tar' '
261 git archive -o config-implicit.baz HEAD &&
262 test_cmp_bin b.tar config-implicit.baz
263'
264
265test_expect_success 'extension matching requires dot' '
266 git archive -o config-implicittar.foo HEAD &&
267 test_cmp_bin b.tar config-implicittar.foo
268'
269
270test_expect_success 'only enabled filters are available remotely' '
271 test_must_fail git archive --remote=. --format=tar.foo HEAD \
272 >remote.tar.foo &&
273 git archive --remote=. --format=bar >remote.bar HEAD &&
274 test_cmp_bin remote.bar config.bar
275'
276
277test_expect_success GZIP 'git archive --format=tgz' '
278 git archive --format=tgz HEAD >j.tgz
279'
280
281test_expect_success GZIP 'git archive --format=tar.gz' '
282 git archive --format=tar.gz HEAD >j1.tar.gz &&
283 test_cmp_bin j.tgz j1.tar.gz
284'
285
286test_expect_success GZIP 'infer tgz from .tgz filename' '
287 git archive --output=j2.tgz HEAD &&
288 test_cmp_bin j.tgz j2.tgz
289'
290
291test_expect_success GZIP 'infer tgz from .tar.gz filename' '
292 git archive --output=j3.tar.gz HEAD &&
293 test_cmp_bin j.tgz j3.tar.gz
294'
295
296test_expect_success GZIP 'extract tgz file' '
297 gzip -d -c <j.tgz >j.tar &&
298 test_cmp_bin b.tar j.tar
299'
300
301test_expect_success GZIP 'remote tar.gz is allowed by default' '
302 git archive --remote=. --format=tar.gz HEAD >remote.tar.gz &&
303 test_cmp_bin j.tgz remote.tar.gz
304'
305
306test_expect_success GZIP 'remote tar.gz can be disabled' '
307 git config tar.tar.gz.remote false &&
308 test_must_fail git archive --remote=. --format=tar.gz HEAD \
309 >remote.tar.gz
310'
311
312test_done