archive: read local configuration
authorJunio C Hamano <gitster@pobox.com>
Tue, 22 Nov 2016 21:37:04 +0000 (13:37 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 22 Nov 2016 21:55:20 +0000 (13:55 -0800)
Since b9605bc4f2 ("config: only read .git/config from configured
repos", 2016-09-12), we do not read from ".git/config" unless we
know we are in a repository. "git archive" however didn't do the
repository discovery and instead relied on the old behaviour.

Teach the command to run a "gentle" version of repository discovery
so that local configuration variables are honoured.

[jc: stole tests from peff]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
archive.c
archive.h
builtin/archive.c
builtin/upload-archive.c
git.c
t/t5000-tar-tree.sh
index dde1ab4c79f87c00ffdd42c37073f459e76da315..01751e574bc10c1211d0253d215917ecc4ce82dd 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -504,15 +504,11 @@ static int parse_archive_args(int argc, const char **argv,
 }
 
 int write_archive(int argc, const char **argv, const char *prefix,
-                 int setup_prefix, const char *name_hint, int remote)
+                 const char *name_hint, int remote)
 {
-       int nongit = 0;
        const struct archiver *ar = NULL;
        struct archiver_args args;
 
-       if (setup_prefix && prefix == NULL)
-               prefix = setup_git_directory_gently(&nongit);
-
        git_config_get_bool("uploadarchive.allowunreachable", &remote_allow_unreachable);
        git_config(git_default_config, NULL);
 
@@ -520,7 +516,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
        init_zip_archiver();
 
        argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
-       if (nongit) {
+       if (!startup_info->have_repository) {
                /*
                 * We know this will die() with an error, so we could just
                 * die ourselves; but its error message will be more specific
index 4a791e1fed4ecb0fc89b309b294acc93793886f0..415e0152e2cf42827b1b370d2e5c78f6e91bd961 100644 (file)
--- a/archive.h
+++ b/archive.h
@@ -36,7 +36,7 @@ typedef int (*write_archive_entry_fn_t)(struct archiver_args *args,
                                        unsigned int mode);
 
 extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
-extern int write_archive(int argc, const char **argv, const char *prefix, int setup_prefix, const char *name_hint, int remote);
+extern int write_archive(int argc, const char **argv, const char *prefix, const char *name_hint, int remote);
 
 const char *archive_format_from_filename(const char *filename);
 extern void *sha1_file_to_archive(const struct archiver_args *args,
index 49f491413a172b3fa21e1f21f7cbdfedba785084..f863465a0fa137f3446071a0ec1653adad536fdc 100644 (file)
@@ -85,8 +85,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
        const char *output = NULL;
        const char *remote = NULL;
        struct option local_opts[] = {
-               OPT_STRING('o', "output", &output, N_("file"),
-                       N_("write the archive to this file")),
+               OPT_FILENAME('o', "output", &output,
+                            N_("write the archive to this file")),
                OPT_STRING(0, "remote", &remote, N_("repo"),
                        N_("retrieve the archive from remote repository <repo>")),
                OPT_STRING(0, "exec", &exec, N_("command"),
@@ -105,5 +105,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
 
        setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
 
-       return write_archive(argc, argv, prefix, 1, output, 0);
+       return write_archive(argc, argv, prefix, output, 0);
 }
index dc872f6a94c09f4390b5898aa499885d7700c737..cde06977b78b1475925e4b6722b5ecdd834847d5 100644 (file)
@@ -43,7 +43,7 @@ int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix)
        }
 
        /* parse all options sent by the client */
-       return write_archive(sent_argv.argc, sent_argv.argv, prefix, 0, NULL, 1);
+       return write_archive(sent_argv.argc, sent_argv.argv, prefix, NULL, 1);
 }
 
 __attribute__((format (printf, 1, 2)))
diff --git a/git.c b/git.c
index fd3abf85d21daa3382361b415e1c66a876da8ad2..e8b2baf2d15c8a68553780c3137c55c3fea99b11 100644 (file)
--- a/git.c
+++ b/git.c
@@ -396,7 +396,7 @@ static struct cmd_struct commands[] = {
        { "am", cmd_am, RUN_SETUP | NEED_WORK_TREE },
        { "annotate", cmd_annotate, RUN_SETUP },
        { "apply", cmd_apply, RUN_SETUP_GENTLY },
-       { "archive", cmd_archive },
+       { "archive", cmd_archive, RUN_SETUP_GENTLY },
        { "bisect--helper", cmd_bisect__helper, RUN_SETUP },
        { "blame", cmd_blame, RUN_SETUP },
        { "branch", cmd_branch, RUN_SETUP },
index 80b2387341c3a7abb9cc4b126376d7dd755d9e1d..830bf2a2f6d4d85358a54f58f74b4ed9fdc954d5 100755 (executable)
@@ -94,6 +94,20 @@ check_tar() {
        '
 }
 
+# run "$@" inside a non-git directory
+nongit () {
+       test -d non-repo ||
+       mkdir non-repo ||
+       return 1
+
+       (
+               GIT_CEILING_DIRECTORIES=$(pwd) &&
+               export GIT_CEILING_DIRECTORIES &&
+               cd non-repo &&
+               "$@"
+       )
+}
+
 test_expect_success \
     'populate workdir' \
     'mkdir a &&
@@ -179,6 +193,15 @@ test_expect_success 'git archive --remote' \
     'git archive --remote=. HEAD >b5.tar &&
     test_cmp_bin b.tar b5.tar'
 
+test_expect_success 'git archive --remote with configured remote' '
+       git config remote.foo.url . &&
+       (
+               cd a &&
+               git archive --remote=foo --output=../b5-nick.tar HEAD
+       ) &&
+       test_cmp_bin b.tar b5-nick.tar
+'
+
 test_expect_success \
     'validate file modification time' \
     'mkdir extract &&
@@ -197,9 +220,15 @@ test_expect_success 'git archive with --output, override inferred format' '
        test_cmp_bin b.tar d4.zip
 '
 
-test_expect_success \
-    'git archive --list outside of a git repo' \
-    'GIT_DIR=some/non-existing/directory git archive --list'
+test_expect_success 'git archive --list outside of a git repo' '
+       nongit git archive --list
+'
+
+test_expect_success 'git archive --remote outside of a git repo' '
+       git archive HEAD >expect.tar &&
+       nongit git archive --remote="$PWD" HEAD >actual.tar &&
+       test_cmp_bin expect.tar actual.tar
+'
 
 test_expect_success 'clients cannot access unreachable commits' '
        test_commit unreachable &&