t / t5004-archive-corner-cases.shon commit Merge branch 'sb/pack-protocol-doc-nak' into maint (593be73)
   1#!/bin/sh
   2
   3test_description='test corner cases of git-archive'
   4. ./test-lib.sh
   5
   6test_expect_success 'create commit with empty tree' '
   7        git commit --allow-empty -m foo
   8'
   9
  10# Make a dir and clean it up afterwards
  11make_dir() {
  12        mkdir "$1" &&
  13        test_when_finished "rm -rf '$1'"
  14}
  15
  16# Check that the dir given in "$1" contains exactly the
  17# set of paths given as arguments.
  18check_dir() {
  19        dir=$1; shift
  20        {
  21                echo "$dir" &&
  22                for i in "$@"; do
  23                        echo "$dir/$i"
  24                done
  25        } | sort >expect &&
  26        find "$dir" ! -name pax_global_header -print | sort >actual &&
  27        test_cmp expect actual
  28}
  29
  30
  31# bsdtar/libarchive versions before 3.1.3 consider a tar file with a
  32# global pax header that is not followed by a file record as corrupt.
  33if "$TAR" tf "$TEST_DIRECTORY"/t5004/empty-with-pax-header.tar >/dev/null 2>&1
  34then
  35        test_set_prereq HEADER_ONLY_TAR_OK
  36fi
  37
  38test_expect_success HEADER_ONLY_TAR_OK 'tar archive of commit with empty tree' '
  39        git archive --format=tar HEAD >empty-with-pax-header.tar &&
  40        make_dir extract &&
  41        "$TAR" xf empty-with-pax-header.tar -C extract &&
  42        check_dir extract
  43'
  44
  45test_expect_success 'tar archive of empty tree is empty' '
  46        git archive --format=tar HEAD: >empty.tar &&
  47        perl -e "print \"\\0\" x 10240" >10knuls.tar &&
  48        test_cmp_bin 10knuls.tar empty.tar
  49'
  50
  51test_expect_success 'tar archive of empty tree with prefix' '
  52        git archive --format=tar --prefix=foo/ HEAD >prefix.tar &&
  53        make_dir extract &&
  54        "$TAR" xf prefix.tar -C extract &&
  55        check_dir extract foo
  56'
  57
  58test_expect_success UNZIP 'zip archive of empty tree is empty' '
  59        # Detect the exit code produced when our particular flavor of unzip
  60        # sees an empty archive. Infozip will generate a warning and exit with
  61        # code 1. But in the name of sanity, we do not expect other unzip
  62        # implementations to do the same thing (it would be perfectly
  63        # reasonable to exit 0, for example).
  64        #
  65        # This makes our test less rigorous on some platforms (unzip may not
  66        # handle the empty repo at all, making our later check of its exit code
  67        # a no-op). But we cannot do anything reasonable except skip the test
  68        # on such platforms anyway, and this is the moral equivalent.
  69        {
  70                "$GIT_UNZIP" "$TEST_DIRECTORY"/t5004/empty.zip
  71                expect_code=$?
  72        } &&
  73
  74        git archive --format=zip HEAD >empty.zip &&
  75        make_dir extract &&
  76        (
  77                cd extract &&
  78                test_expect_code $expect_code "$GIT_UNZIP" ../empty.zip
  79        ) &&
  80        check_dir extract
  81'
  82
  83test_expect_success UNZIP 'zip archive of empty tree with prefix' '
  84        # We do not have to play exit-code tricks here, because our
  85        # result should not be empty; it has a directory in it.
  86        git archive --format=zip --prefix=foo/ HEAD >prefix.zip &&
  87        make_dir extract &&
  88        (
  89                cd extract &&
  90                "$GIT_UNZIP" ../prefix.zip
  91        ) &&
  92        check_dir extract foo
  93'
  94
  95test_expect_success 'archive complains about pathspec on empty tree' '
  96        test_must_fail git archive --format=tar HEAD -- foo >/dev/null
  97'
  98
  99test_expect_success 'create a commit with an empty subtree' '
 100        empty_tree=$(git hash-object -t tree /dev/null) &&
 101        root_tree=$(printf "040000 tree $empty_tree\tsub\n" | git mktree)
 102'
 103
 104test_expect_success 'archive empty subtree with no pathspec' '
 105        git archive --format=tar $root_tree >subtree-all.tar &&
 106        make_dir extract &&
 107        "$TAR" xf subtree-all.tar -C extract &&
 108        check_dir extract sub
 109'
 110
 111test_expect_success 'archive empty subtree by direct pathspec' '
 112        git archive --format=tar $root_tree -- sub >subtree-path.tar &&
 113        make_dir extract &&
 114        "$TAR" xf subtree-path.tar -C extract &&
 115        check_dir extract sub
 116'
 117
 118ZIPINFO=zipinfo
 119
 120test_lazy_prereq ZIPINFO '
 121        n=$("$ZIPINFO" "$TEST_DIRECTORY"/t5004/empty.zip | sed -n "2s/.* //p")
 122        test "x$n" = "x0"
 123'
 124
 125test_expect_success ZIPINFO 'zip archive with many entries' '
 126        # add a directory with 256 files
 127        mkdir 00 &&
 128        for a in 0 1 2 3 4 5 6 7 8 9 a b c d e f
 129        do
 130                for b in 0 1 2 3 4 5 6 7 8 9 a b c d e f
 131                do
 132                        : >00/$a$b
 133                done
 134        done &&
 135        git add 00 &&
 136        git commit -m "256 files in 1 directory" &&
 137
 138        # duplicate it to get 65536 files in 256 directories
 139        subtree=$(git write-tree --prefix=00/) &&
 140        for c in 0 1 2 3 4 5 6 7 8 9 a b c d e f
 141        do
 142                for d in 0 1 2 3 4 5 6 7 8 9 a b c d e f
 143                do
 144                        echo "040000 tree $subtree      $c$d"
 145                done
 146        done >tree &&
 147        tree=$(git mktree <tree) &&
 148
 149        # zip them
 150        git archive -o many.zip $tree &&
 151
 152        # check the number of entries in the ZIP file directory
 153        expr 65536 + 256 >expect &&
 154        "$ZIPINFO" many.zip | head -2 | sed -n "2s/.* //p" >actual &&
 155        test_cmp expect actual
 156'
 157
 158test_done