Merge branch 'jk/empty-archive' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 3 Apr 2013 16:25:15 +0000 (09:25 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 3 Apr 2013 16:25:15 +0000 (09:25 -0700)
"git archive" reports a failure when asked to create an archive out
of an empty tree. It would be more intuitive to give an empty
archive back in such a case.

* jk/empty-archive:
archive: handle commits with an empty tree
test-lib: factor out $GIT_UNZIP setup

archive.c
t/t0024-crlf-archive.sh
t/t5003-archive-zip.sh
t/t5004-archive-corner-cases.sh [new file with mode: 0755]
t/t5004/empty.zip [new file with mode: 0644]
t/test-lib.sh
index 93e00bb4ae8ff9637be9e55fd41536b8837c3ba2..d254fa5d5cc32b0254dc863d015bc3d97dc59681 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -234,7 +234,7 @@ static void parse_pathspec_arg(const char **pathspec,
        ar_args->pathspec = pathspec = get_pathspec("", pathspec);
        if (pathspec) {
                while (*pathspec) {
-                       if (!path_exists(ar_args->tree, *pathspec))
+                       if (**pathspec && !path_exists(ar_args->tree, *pathspec))
                                die("path not found: %s", *pathspec);
                        pathspec++;
                }
index 5378787e1b23bf18796c28c33533f677b389289c..4e9fa3cd68426942357d8f89ffa97ed3099e1084 100755 (executable)
@@ -3,12 +3,6 @@
 test_description='respect crlf in git archive'
 
 . ./test-lib.sh
-GIT_UNZIP=${GIT_UNZIP:-unzip}
-
-test_lazy_prereq UNZIP '
-       "$GIT_UNZIP" -v
-       test $? -ne 127
-'
 
 test_expect_success setup '
 
index 6a33606d28eba61281252cf28f6d5820dc452f1d..4e7b05dd2391125b1c9e58404c552647107099cd 100755 (executable)
@@ -3,15 +3,9 @@
 test_description='git archive --format=zip test'
 
 . ./test-lib.sh
-GIT_UNZIP=${GIT_UNZIP:-unzip}
 
 SUBSTFORMAT=%H%n
 
-test_lazy_prereq UNZIP '
-       "$GIT_UNZIP" -v
-       test $? -ne 127
-'
-
 test_lazy_prereq UNZIP_SYMLINKS '
        (
                mkdir unzip-symlinks &&
diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh
new file mode 100755 (executable)
index 0000000..cdb7d7a
--- /dev/null
@@ -0,0 +1,102 @@
+#!/bin/sh
+
+test_description='test corner cases of git-archive'
+. ./test-lib.sh
+
+test_expect_success 'create commit with empty tree' '
+       git commit --allow-empty -m foo
+'
+
+# Make a dir and clean it up afterwards
+make_dir() {
+       mkdir "$1" &&
+       test_when_finished "rm -rf '$1'"
+}
+
+# Check that the dir given in "$1" contains exactly the
+# set of paths given as arguments.
+check_dir() {
+       dir=$1; shift
+       {
+               echo "$dir" &&
+               for i in "$@"; do
+                       echo "$dir/$i"
+               done
+       } | sort >expect &&
+       find "$dir" -print | sort >actual &&
+       test_cmp expect actual
+}
+
+test_expect_success 'tar archive of empty tree is empty' '
+       git archive --format=tar HEAD >empty.tar &&
+       make_dir extract &&
+       "$TAR" xf empty.tar -C extract &&
+       check_dir extract
+'
+
+test_expect_success 'tar archive of empty tree with prefix' '
+       git archive --format=tar --prefix=foo/ HEAD >prefix.tar &&
+       make_dir extract &&
+       "$TAR" xf prefix.tar -C extract &&
+       check_dir extract foo
+'
+
+test_expect_success UNZIP 'zip archive of empty tree is empty' '
+       # Detect the exit code produced when our particular flavor of unzip
+       # sees an empty archive. Infozip will generate a warning and exit with
+       # code 1. But in the name of sanity, we do not expect other unzip
+       # implementations to do the same thing (it would be perfectly
+       # reasonable to exit 0, for example).
+       #
+       # This makes our test less rigorous on some platforms (unzip may not
+       # handle the empty repo at all, making our later check of its exit code
+       # a no-op). But we cannot do anything reasonable except skip the test
+       # on such platforms anyway, and this is the moral equivalent.
+       "$GIT_UNZIP" "$TEST_DIRECTORY"/t5004/empty.zip
+       expect_code=$?
+
+       git archive --format=zip HEAD >empty.zip &&
+       make_dir extract &&
+       (
+               cd extract &&
+               test_expect_code $expect_code "$GIT_UNZIP" ../empty.zip
+       ) &&
+       check_dir extract
+'
+
+test_expect_success UNZIP 'zip archive of empty tree with prefix' '
+       # We do not have to play exit-code tricks here, because our
+       # result should not be empty; it has a directory in it.
+       git archive --format=zip --prefix=foo/ HEAD >prefix.zip &&
+       make_dir extract &&
+       (
+               cd extract &&
+               "$GIT_UNZIP" ../prefix.zip
+       ) &&
+       check_dir extract foo
+'
+
+test_expect_success 'archive complains about pathspec on empty tree' '
+       test_must_fail git archive --format=tar HEAD -- foo >/dev/null
+'
+
+test_expect_success 'create a commit with an empty subtree' '
+       empty_tree=$(git hash-object -t tree /dev/null) &&
+       root_tree=$(printf "040000 tree $empty_tree\tsub\n" | git mktree)
+'
+
+test_expect_success 'archive empty subtree with no pathspec' '
+       git archive --format=tar $root_tree >subtree-all.tar &&
+       make_dir extract &&
+       "$TAR" xf subtree-all.tar -C extract &&
+       check_dir extract sub
+'
+
+test_expect_success 'archive empty subtree by direct pathspec' '
+       git archive --format=tar $root_tree -- sub >subtree-path.tar &&
+       make_dir extract &&
+       "$TAR" xf subtree-path.tar -C extract &&
+       check_dir extract sub
+'
+
+test_done
diff --git a/t/t5004/empty.zip b/t/t5004/empty.zip
new file mode 100644 (file)
index 0000000..1a76bb6
Binary files /dev/null and b/t/t5004/empty.zip differ
index 9e7f6b424d77ee88c3cd36507cd421a437ec7bfa..1f510252ad7cb7a5afae67731bc37fccf941b654 100644 (file)
@@ -760,3 +760,9 @@ test_lazy_prereq AUTOIDENT '
 # When the tests are run as root, permission tests will report that
 # things are writable when they shouldn't be.
 test -w / || test_set_prereq SANITY
+
+GIT_UNZIP=${GIT_UNZIP:-unzip}
+test_lazy_prereq UNZIP '
+       "$GIT_UNZIP" -v
+       test $? -ne 127
+'