Merge branch 'sg/doc-show-branch-typofix'
[gitweb.git] / transport.c
index 4329cca8e5a831db1892d57cd75f3d06bed3e94a..01ce11a32575fc8ca889ba99f610983ef150688d 100644 (file)
@@ -733,6 +733,7 @@ static int disconnect_git(struct transport *transport)
 }
 
 static struct transport_vtable taken_over_vtable = {
+       1,
        NULL,
        get_refs_via_connect,
        fetch_refs_via_pack,
@@ -882,6 +883,7 @@ void transport_check_allowed(const char *type)
 }
 
 static struct transport_vtable bundle_vtable = {
+       0,
        NULL,
        get_refs_from_bundle,
        fetch_refs_from_bundle,
@@ -891,6 +893,7 @@ static struct transport_vtable bundle_vtable = {
 };
 
 static struct transport_vtable builtin_smart_vtable = {
+       1,
        NULL,
        get_refs_via_connect,
        fetch_refs_via_pack,
@@ -1169,7 +1172,8 @@ int transport_push(struct transport *transport,
                                        oid_array_append(&commits,
                                                          &ref->new_oid);
 
-                       if (!push_unpushed_submodules(&commits,
+                       if (!push_unpushed_submodules(&the_index,
+                                                     &commits,
                                                      transport->remote,
                                                      rs,
                                                      transport->push_options,
@@ -1193,8 +1197,10 @@ int transport_push(struct transport *transport,
                                        oid_array_append(&commits,
                                                          &ref->new_oid);
 
-                       if (find_unpushed_submodules(&commits, transport->remote->name,
-                                               &needs_pushing)) {
+                       if (find_unpushed_submodules(&the_index,
+                                                    &commits,
+                                                    transport->remote->name,
+                                                    &needs_pushing)) {
                                oid_array_clear(&commits);
                                die_with_unpushed_submodules(&needs_pushing);
                        }
@@ -1254,6 +1260,15 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
        struct ref **heads = NULL;
        struct ref *rm;
 
+       if (!transport->vtable->fetch_without_list)
+               /*
+                * Some transports (e.g. the built-in bundle transport and the
+                * transport helper interface) do not work when fetching is
+                * done immediately after transport creation. List the remote
+                * refs anyway (if not already listed) as a workaround.
+                */
+               transport_get_remote_refs(transport, NULL);
+
        for (rm = refs; rm; rm = rm->next) {
                nr_refs++;
                if (rm->peer_ref &&
@@ -1355,6 +1370,33 @@ char *transport_anonymize_url(const char *url)
        return xstrdup(url);
 }
 
+static void fill_alternate_refs_command(struct child_process *cmd,
+                                       const char *repo_path)
+{
+       const char *value;
+
+       if (!git_config_get_value("core.alternateRefsCommand", &value)) {
+               cmd->use_shell = 1;
+
+               argv_array_push(&cmd->args, value);
+               argv_array_push(&cmd->args, repo_path);
+       } else {
+               cmd->git_cmd = 1;
+
+               argv_array_pushf(&cmd->args, "--git-dir=%s", repo_path);
+               argv_array_push(&cmd->args, "for-each-ref");
+               argv_array_push(&cmd->args, "--format=%(objectname)");
+
+               if (!git_config_get_value("core.alternateRefsPrefixes", &value)) {
+                       argv_array_push(&cmd->args, "--");
+                       argv_array_split(&cmd->args, value);
+               }
+       }
+
+       cmd->env = local_repo_env;
+       cmd->out = -1;
+}
+
 static void read_alternate_refs(const char *path,
                                alternate_ref_fn *cb,
                                void *data)
@@ -1363,12 +1405,7 @@ static void read_alternate_refs(const char *path,
        struct strbuf line = STRBUF_INIT;
        FILE *fh;
 
-       cmd.git_cmd = 1;
-       argv_array_pushf(&cmd.args, "--git-dir=%s", path);
-       argv_array_push(&cmd.args, "for-each-ref");
-       argv_array_push(&cmd.args, "--format=%(objectname) %(refname)");
-       cmd.env = local_repo_env;
-       cmd.out = -1;
+       fill_alternate_refs_command(&cmd, path);
 
        if (start_command(&cmd))
                return;
@@ -1376,15 +1413,15 @@ static void read_alternate_refs(const char *path,
        fh = xfdopen(cmd.out, "r");
        while (strbuf_getline_lf(&line, fh) != EOF) {
                struct object_id oid;
+               const char *p;
 
-               if (get_oid_hex(line.buf, &oid) ||
-                   line.buf[GIT_SHA1_HEXSZ] != ' ') {
+               if (parse_oid_hex(line.buf, &oid, &p) || *p) {
                        warning(_("invalid line while parsing alternate refs: %s"),
                                line.buf);
                        break;
                }
 
-               cb(line.buf + GIT_SHA1_HEXSZ + 1, &oid, data);
+               cb(&oid, data);
        }
 
        fclose(fh);