Merge branch 'jn/remote-helpers-with-git-dir'
authorJunio C Hamano <gitster@pobox.com>
Mon, 27 Feb 2017 21:57:16 +0000 (13:57 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 27 Feb 2017 21:57:16 +0000 (13:57 -0800)
"git ls-remote" and "git archive --remote" are designed to work
without being in a directory under Git's control. However, recent
updates revealed that we randomly look into a directory called
.git/ without actually doing necessary set-up when working in a
repository. Stop doing so.

* jn/remote-helpers-with-git-dir:
remote helpers: avoid blind fall-back to ".git" when setting GIT_DIR
remote: avoid reading $GIT_DIR config in non-repo

1  2 
remote.c
t/t5550-http-fetch-dumb.sh
transport-helper.c
diff --combined remote.c
index bf1bf2309128bf886eac16959b8162b9990c98d7,81e4ea873adfe4c1a9480769f88fe74f05c1f9d9..9f83fe2c4cbd477e47fc6c81eab324be7aa088c6
+++ b/remote.c
@@@ -255,7 -255,6 +255,7 @@@ static void read_remotes_file(struct re
  
        if (!f)
                return;
 +      remote->configured_in_repo = 1;
        remote->origin = REMOTE_REMOTES;
        while (strbuf_getline(&buf, f) != EOF) {
                const char *v;
@@@ -290,7 -289,6 +290,7 @@@ static void read_branches_file(struct r
                return;
        }
  
 +      remote->configured_in_repo = 1;
        remote->origin = REMOTE_BRANCHES;
  
        /*
@@@ -373,8 -371,6 +373,8 @@@ static int handle_config(const char *ke
        }
        remote = make_remote(name, namelen);
        remote->origin = REMOTE_CONFIG;
 +      if (current_config_scope() == CONFIG_SCOPE_REPO)
 +              remote->configured_in_repo = 1;
        if (!strcmp(subkey, "mirror"))
                remote->mirror = git_config_bool(key, value);
        else if (!strcmp(subkey, "skipdefaultupdate"))
@@@ -693,7 -689,7 +693,7 @@@ static struct remote *remote_get_1(cons
                name = get_default(current_branch, &name_given);
  
        ret = make_remote(name, 0);
-       if (valid_remote_nick(name)) {
+       if (valid_remote_nick(name) && have_git_dir()) {
                if (!valid_remote(ret))
                        read_remotes_file(ret);
                if (!valid_remote(ret))
@@@ -718,13 -714,9 +718,13 @@@ struct remote *pushremote_get(const cha
        return remote_get_1(name, pushremote_for_branch);
  }
  
 -int remote_is_configured(struct remote *remote)
 +int remote_is_configured(struct remote *remote, int in_repo)
  {
 -      return remote && remote->origin;
 +      if (!remote)
 +              return 0;
 +      if (in_repo)
 +              return remote->configured_in_repo;
 +      return !!remote->origin;
  }
  
  int for_each_remote(each_remote_fn fn, void *priv)
index aeb3a63f7c07caa3f53ff4da5096dc51493dd4e3,d66ef43cb742f366f074ab28f3dc4b56a73149c9..b69ece1d66f2b076ff94904dc7fddb7c7c1c88c5
@@@ -34,6 -34,15 +34,15 @@@ test_expect_success 'clone http reposit
        test_cmp file clone/file
  '
  
+ test_expect_success 'list refs from outside any repository' '
+       cat >expect <<-EOF &&
+       $(git rev-parse master) HEAD
+       $(git rev-parse master) refs/heads/master
+       EOF
+       nongit git ls-remote "$HTTPD_URL/dumb/repo.git" >actual &&
+       test_cmp expect actual
+ '
  test_expect_success 'create password-protected repository' '
        mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/" &&
        cp -Rf "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
@@@ -368,15 -377,5 +377,15 @@@ test_expect_success 'http-alternates ca
                clone "$HTTPD_URL/dumb/evil.git" evil-file
  '
  
 +test_expect_success 'http-alternates triggers not-from-user protocol check' '
 +      echo "$HTTPD_URL/dumb/victim.git/objects" \
 +              >"$evil/objects/info/http-alternates" &&
 +      test_config_global http.followRedirects true &&
 +      test_must_fail git -c protocol.http.allow=user \
 +              clone $HTTPD_URL/dumb/evil.git evil-user &&
 +      git -c protocol.http.allow=always \
 +              clone $HTTPD_URL/dumb/evil.git evil-user
 +'
 +
  stop_httpd
  test_done
diff --combined transport-helper.c
index 1258d6aedd26538f55c60495a61608236262cfc1,e4fd98238308de91b1a242335db236fd43d2ecc5..dc90a1fb769c078be2fbf77018242b6fc209acf6
@@@ -124,8 -124,9 +124,9 @@@ static struct child_process *get_helper
        helper->git_cmd = 0;
        helper->silent_exec_failure = 1;
  
-       argv_array_pushf(&helper->env_array, "%s=%s", GIT_DIR_ENVIRONMENT,
-                        get_git_dir());
+       if (have_git_dir())
+               argv_array_pushf(&helper->env_array, "%s=%s",
+                                GIT_DIR_ENVIRONMENT, get_git_dir());
  
        code = start_command(helper);
        if (code < 0 && errno == ENOENT)
@@@ -826,13 -827,6 +827,13 @@@ static void set_common_push_options(str
                if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "if-asked") != 0)
                        die("helper %s does not support --signed=if-asked", name);
        }
 +
 +      if (flags & TRANSPORT_PUSH_OPTIONS) {
 +              struct string_list_item *item;
 +              for_each_string_list_item(item, transport->push_options)
 +                      if (set_helper_option(transport, "push-option", item->string) != 0)
 +                              die("helper %s does not support 'push-option'", name);
 +      }
  }
  
  static int push_refs_with_push(struct transport *transport,