Merge branch 'mw/symlinks'
[git] / t / t5000-tar-tree.sh
1 #!/bin/sh
2 #
3 # Copyright (C) 2005 Rene Scharfe
4 #
5
6 test_description='git archive and git get-tar-commit-id test
7
8 This test covers the topics of file contents, commit date handling and
9 commit 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
29 SUBSTFORMAT=%H%n
30
31 test_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
40 test_lazy_prereq GZIP 'gzip --version'
41
42 get_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
59 check_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
97 test_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
117 test_expect_success \
118     'add ignored file' \
119     'echo ignore me >a/ignored &&
120      echo ignored export-ignore >.git/info/attributes'
121
122 test_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
131 test_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
137 test_expect_success \
138     'create bare clone' \
139     'git clone --bare . bare.git &&
140      cp .git/info/attributes bare.git/info/attributes'
141
142 test_expect_success \
143     'remove ignored file' \
144     'rm a/ignored'
145
146 test_expect_success \
147     'git archive' \
148     'git archive HEAD >b.tar'
149
150 check_tar b
151
152 test_expect_success 'git archive --prefix=prefix/' '
153         git archive --prefix=prefix/ HEAD >with_prefix.tar
154 '
155
156 check_tar with_prefix prefix/
157
158 test_expect_success 'git-archive --prefix=olde-' '
159         git archive --prefix=olde- HEAD >with_olde-prefix.tar
160 '
161
162 check_tar with_olde-prefix olde-
163
164 test_expect_success 'git archive on large files' '
165     test_config core.bigfilethreshold 1 &&
166     git archive HEAD >b3.tar &&
167     test_cmp b.tar b3.tar
168 '
169
170 test_expect_success \
171     'git archive in a bare repo' \
172     '(cd bare.git && git archive HEAD) >b3.tar'
173
174 test_expect_success \
175     'git archive vs. the same in a bare repo' \
176     'test_cmp b.tar b3.tar'
177
178 test_expect_success 'git archive with --output' \
179     'git archive --output=b4.tar HEAD &&
180     test_cmp b.tar b4.tar'
181
182 test_expect_success 'git archive --remote' \
183     'git archive --remote=. HEAD >b5.tar &&
184     test_cmp b.tar b5.tar'
185
186 test_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
194 test_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
199 test_expect_success 'git archive with --output, override inferred format' '
200         git archive --format=tar --output=d4.zip HEAD &&
201         test_cmp b.tar d4.zip
202 '
203
204 test_expect_success \
205     'git archive --list outside of a git repo' \
206     'GIT_DIR=some/non-existing/directory git archive --list'
207
208 test_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
216 test_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
225 test_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
232 test_expect_success 'archive --list mentions user filter' '
233         git archive --list >output &&
234         grep "^tar\.foo\$" output &&
235         grep "^bar\$" output
236 '
237
238 test_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
244 test_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 b.tar config.tar &&
248         git archive --format=bar HEAD >config.bar &&
249         tr ab ba <config.bar >config.tar &&
250         test_cmp b.tar config.tar
251 '
252
253 test_expect_success 'invoke tar filter by extension' '
254         git archive -o config-implicit.tar.foo HEAD &&
255         test_cmp config.tar.foo config-implicit.tar.foo &&
256         git archive -o config-implicit.bar HEAD &&
257         test_cmp config.tar.foo config-implicit.bar
258 '
259
260 test_expect_success 'default output format remains tar' '
261         git archive -o config-implicit.baz HEAD &&
262         test_cmp b.tar config-implicit.baz
263 '
264
265 test_expect_success 'extension matching requires dot' '
266         git archive -o config-implicittar.foo HEAD &&
267         test_cmp b.tar config-implicittar.foo
268 '
269
270 test_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 remote.bar config.bar
275 '
276
277 test_expect_success GZIP 'git archive --format=tgz' '
278         git archive --format=tgz HEAD >j.tgz
279 '
280
281 test_expect_success GZIP 'git archive --format=tar.gz' '
282         git archive --format=tar.gz HEAD >j1.tar.gz &&
283         test_cmp j.tgz j1.tar.gz
284 '
285
286 test_expect_success GZIP 'infer tgz from .tgz filename' '
287         git archive --output=j2.tgz HEAD &&
288         test_cmp j.tgz j2.tgz
289 '
290
291 test_expect_success GZIP 'infer tgz from .tar.gz filename' '
292         git archive --output=j3.tar.gz HEAD &&
293         test_cmp j.tgz j3.tar.gz
294 '
295
296 test_expect_success GZIP 'extract tgz file' '
297         gzip -d -c <j.tgz >j.tar &&
298         test_cmp b.tar j.tar
299 '
300
301 test_expect_success GZIP 'remote tar.gz is allowed by default' '
302         git archive --remote=. --format=tar.gz HEAD >remote.tar.gz &&
303         test_cmp j.tgz remote.tar.gz
304 '
305
306 test_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
312 test_done