1#!/bin/sh
   2#
   3# Copyright (C) 2005 Rene Scharfe
   4#
   5test_description='git archive and git get-tar-commit-id test
   7This test covers the topics of file contents, commit date handling and
   9commit id embedding:
  10  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  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  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'
  26. ./test-lib.sh
  28SUBSTFORMAT=%H%n
  30test_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'
  39test_lazy_prereq GZIP 'gzip --version'
  41get_pax_header() {
  43        file=$1
  44        header=$2=
  45        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}
  58check_tar() {
  60        tarfile=$1.tar
  61        listfile=$1.lst
  62        dir=$1
  63        dir_with_prefix=$dir/$2
  64        test_expect_success ' extract tar archive' '
  66                (mkdir $dir && cd $dir && "$TAR" xf -) <$tarfile
  67        '
  68        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        test_expect_success ' validate filenames' '
  88                (cd ${dir_with_prefix}a && find .) | sort >$listfile &&
  89                test_cmp a.lst $listfile
  90        '
  91        test_expect_success ' validate file contents' '
  93                diff -r a ${dir_with_prefix}a
  94        '
  95}
  96test_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'
 116test_expect_success \
 118    'add ignored file' \
 119    'echo ignore me >a/ignored &&
 120     echo ignored export-ignore >.git/info/attributes'
 121test_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)'
 130test_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'
 136test_expect_success \
 138    'create bare clone' \
 139    'git clone --bare . bare.git &&
 140     cp .git/info/attributes bare.git/info/attributes'
 141test_expect_success \
 143    'remove ignored file' \
 144    'rm a/ignored'
 145test_expect_success \
 147    'git archive' \
 148    'git archive HEAD >b.tar'
 149check_tar b
 151test_expect_success 'git archive --prefix=prefix/' '
 153        git archive --prefix=prefix/ HEAD >with_prefix.tar
 154'
 155check_tar with_prefix prefix/
 157test_expect_success 'git-archive --prefix=olde-' '
 159        git archive --prefix=olde- HEAD >with_olde-prefix.tar
 160'
 161check_tar with_olde-prefix olde-
 163test_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'
 169test_expect_success \
 171    'git archive in a bare repo' \
 172    '(cd bare.git && git archive HEAD) >b3.tar'
 173test_expect_success \
 175    'git archive vs. the same in a bare repo' \
 176    'test_cmp b.tar b3.tar'
 177test_expect_success 'git archive with --output' \
 179    'git archive --output=b4.tar HEAD &&
 180    test_cmp b.tar b4.tar'
 181test_expect_success 'git archive --remote' \
 183    'git archive --remote=. HEAD >b5.tar &&
 184    test_cmp b.tar b5.tar'
 185test_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'
 193test_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'
 198test_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'
 203test_expect_success \
 205    'git archive --list outside of a git repo' \
 206    'GIT_DIR=some/non-existing/directory git archive --list'
 207test_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'
 215test_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'
 224test_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'
 231test_expect_success 'archive --list mentions user filter' '
 233        git archive --list >output &&
 234        grep "^tar\.foo\$" output &&
 235        grep "^bar\$" output
 236'
 237test_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'
 243test_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'
 252test_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'
 259test_expect_success 'default output format remains tar' '
 261        git archive -o config-implicit.baz HEAD &&
 262        test_cmp b.tar config-implicit.baz
 263'
 264test_expect_success 'extension matching requires dot' '
 266        git archive -o config-implicittar.foo HEAD &&
 267        test_cmp b.tar config-implicittar.foo
 268'
 269test_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'
 276test_expect_success GZIP 'git archive --format=tgz' '
 278        git archive --format=tgz HEAD >j.tgz
 279'
 280test_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'
 285test_expect_success GZIP 'infer tgz from .tgz filename' '
 287        git archive --output=j2.tgz HEAD &&
 288        test_cmp j.tgz j2.tgz
 289'
 290test_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'
 295test_expect_success GZIP 'extract tgz file' '
 297        gzip -d -c <j.tgz >j.tar &&
 298        test_cmp b.tar j.tar
 299'
 300test_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'
 305test_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'
 311test_done