i18n: fix small typos
[gitweb.git] / transport.c
index b64b7bcb86f3c807d6a0dcd1dce26c7ee7fbb966..5a74b609ffad51752ec91cc93c602f00292288d1 100644 (file)
@@ -139,7 +139,7 @@ static struct ref *get_refs_from_bundle(struct transport *transport,
                close(data->fd);
        data->fd = read_bundle_header(transport->url, &data->header);
        if (data->fd < 0)
-               die ("Could not read bundle '%s'.", transport->url);
+               die(_("could not read bundle '%s'"), transport->url);
        for (i = 0; i < data->header.references.nr; i++) {
                struct ref_list_entry *e = data->header.references.list + i;
                struct ref *ref = alloc_ref(e->name);
@@ -151,8 +151,7 @@ static struct ref *get_refs_from_bundle(struct transport *transport,
 }
 
 static int fetch_refs_from_bundle(struct transport *transport,
-                              int nr_heads, struct ref **to_fetch,
-                              struct ref **fetched_refs)
+                              int nr_heads, struct ref **to_fetch)
 {
        struct bundle_transport_data *data = transport->data;
        return unbundle(&data->header, data->fd,
@@ -253,8 +252,18 @@ static int connect_setup(struct transport *transport, int for_push)
        return 0;
 }
 
-static struct ref *get_refs_via_connect(struct transport *transport, int for_push,
-                                       const struct argv_array *ref_prefixes)
+/*
+ * Obtains the protocol version from the transport and writes it to
+ * transport->data->version, first connecting if not already connected.
+ *
+ * If the protocol version is one that allows skipping the listing of remote
+ * refs, and must_list_refs is 0, the listing of remote refs is skipped and
+ * this function returns NULL. Otherwise, this function returns the list of
+ * remote refs.
+ */
+static struct ref *handshake(struct transport *transport, int for_push,
+                            const struct argv_array *ref_prefixes,
+                            int must_list_refs)
 {
        struct git_transport_data *data = transport->data;
        struct ref *refs = NULL;
@@ -269,8 +278,10 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus
        data->version = discover_version(&reader);
        switch (data->version) {
        case protocol_v2:
-               get_remote_refs(data->fd[1], &reader, &refs, for_push,
-                               ref_prefixes, transport->server_options);
+               if (must_list_refs)
+                       get_remote_refs(data->fd[1], &reader, &refs, for_push,
+                                       ref_prefixes,
+                                       transport->server_options);
                break;
        case protocol_v1:
        case protocol_v0:
@@ -284,12 +295,20 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus
        }
        data->got_remote_heads = 1;
 
+       if (reader.line_peeked)
+               BUG("buffer must be empty at the end of handshake()");
+
        return refs;
 }
 
+static struct ref *get_refs_via_connect(struct transport *transport, int for_push,
+                                       const struct argv_array *ref_prefixes)
+{
+       return handshake(transport, for_push, ref_prefixes, 1);
+}
+
 static int fetch_refs_via_pack(struct transport *transport,
-                              int nr_heads, struct ref **to_fetch,
-                              struct ref **fetched_refs)
+                              int nr_heads, struct ref **to_fetch)
 {
        int ret = 0;
        struct git_transport_data *data = transport->data;
@@ -322,8 +341,17 @@ static int fetch_refs_via_pack(struct transport *transport,
        args.server_options = transport->server_options;
        args.negotiation_tips = data->options.negotiation_tips;
 
-       if (!data->got_remote_heads)
-               refs_tmp = get_refs_via_connect(transport, 0, NULL);
+       if (!data->got_remote_heads) {
+               int i;
+               int must_list_refs = 0;
+               for (i = 0; i < nr_heads; i++) {
+                       if (!to_fetch[i]->exact_oid) {
+                               must_list_refs = 1;
+                               break;
+                       }
+               }
+               refs_tmp = handshake(transport, 0, NULL, must_list_refs);
+       }
 
        switch (data->version) {
        case protocol_v2:
@@ -358,12 +386,8 @@ static int fetch_refs_via_pack(struct transport *transport,
        if (report_unmatched_refs(to_fetch, nr_heads))
                ret = -1;
 
-       if (fetched_refs)
-               *fetched_refs = refs;
-       else
-               free_refs(refs);
-
        free_refs(refs_tmp);
+       free_refs(refs);
        free(dest);
        return ret;
 }
@@ -662,7 +686,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
 
        switch (data->version) {
        case protocol_v2:
-               die("support for protocol v2 not implemented yet");
+               die(_("support for protocol v2 not implemented yet"));
                break;
        case protocol_v1:
        case protocol_v0:
@@ -709,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,
@@ -788,7 +813,7 @@ static enum protocol_allow_config parse_protocol_config(const char *key,
        else if (!strcasecmp(value, "user"))
                return PROTOCOL_ALLOW_USER_ONLY;
 
-       die("unknown value for config '%s': %s", key, value);
+       die(_("unknown value for config '%s': %s"), key, value);
 }
 
 static enum protocol_allow_config get_protocol_config(const char *type)
@@ -854,10 +879,11 @@ int is_transport_allowed(const char *type, int from_user)
 void transport_check_allowed(const char *type)
 {
        if (!is_transport_allowed(type, -1))
-               die("transport '%s' not allowed", type);
+               die(_("transport '%s' not allowed"), type);
 }
 
 static struct transport_vtable bundle_vtable = {
+       0,
        NULL,
        get_refs_from_bundle,
        fetch_refs_from_bundle,
@@ -867,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,
@@ -883,7 +910,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
        ret->progress = isatty(2);
 
        if (!remote)
-               die("No remote provided to transport_get()");
+               BUG("No remote provided to transport_get()");
 
        ret->got_remote_refs = 0;
        ret->remote = remote;
@@ -906,7 +933,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
        if (helper) {
                transport_helper_init(ret, helper);
        } else if (starts_with(url, "rsync:")) {
-               die("git-over-rsync is no longer supported");
+               die(_("git-over-rsync is no longer supported"));
        } else if (url_is_local_not_ssh(url) && is_file(url) && is_bundle(url, 1)) {
                struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
                transport_check_allowed("file");
@@ -1145,13 +1172,14 @@ int transport_push(struct transport *transport,
                                        oid_array_append(&commits,
                                                          &ref->new_oid);
 
-                       if (!push_unpushed_submodules(&commits,
+                       if (!push_unpushed_submodules(the_repository,
+                                                     &commits,
                                                      transport->remote,
                                                      rs,
                                                      transport->push_options,
                                                      pretend)) {
                                oid_array_clear(&commits);
-                               die("Failed to push all needed submodules!");
+                               die(_("failed to push all needed submodules"));
                        }
                        oid_array_clear(&commits);
                }
@@ -1169,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_repository,
+                                                    &commits,
+                                                    transport->remote->name,
+                                                    &needs_pushing)) {
                                oid_array_clear(&commits);
                                die_with_unpushed_submodules(&needs_pushing);
                        }
@@ -1223,31 +1253,28 @@ const struct ref *transport_get_remote_refs(struct transport *transport,
        return transport->remote_refs;
 }
 
-int transport_fetch_refs(struct transport *transport, struct ref *refs,
-                        struct ref **fetched_refs)
+int transport_fetch_refs(struct transport *transport, struct ref *refs)
 {
        int rc;
        int nr_heads = 0, nr_alloc = 0, nr_refs = 0;
        struct ref **heads = NULL;
-       struct ref *nop_head = NULL, **nop_tail = &nop_head;
        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 &&
                    !is_null_oid(&rm->old_oid) &&
-                   !oidcmp(&rm->peer_ref->old_oid, &rm->old_oid)) {
-                       /*
-                        * These need to be reported as fetched, but we don't
-                        * actually need to fetch them.
-                        */
-                       if (fetched_refs) {
-                               struct ref *nop_ref = copy_ref(rm);
-                               *nop_tail = nop_ref;
-                               nop_tail = &nop_ref->next;
-                       }
+                   oideq(&rm->peer_ref->old_oid, &rm->old_oid))
                        continue;
-               }
                ALLOC_GROW(heads, nr_heads + 1, nr_alloc);
                heads[nr_heads++] = rm;
        }
@@ -1265,11 +1292,7 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs,
                        heads[nr_heads++] = rm;
        }
 
-       rc = transport->vtable->fetch(transport, nr_heads, heads, fetched_refs);
-       if (fetched_refs && nop_head) {
-               *nop_tail = *fetched_refs;
-               *fetched_refs = nop_head;
-       }
+       rc = transport->vtable->fetch(transport, nr_heads, heads);
 
        free(heads);
        return rc;
@@ -1289,7 +1312,7 @@ int transport_connect(struct transport *transport, const char *name,
        if (transport->vtable->connect)
                return transport->vtable->connect(transport, name, exec, fd);
        else
-               die("Operation not supported by protocol");
+               die(_("operation not supported by protocol"));
 }
 
 int transport_disconnect(struct transport *transport)
@@ -1347,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)
@@ -1355,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;
@@ -1368,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] != ' ') {
-                       warning("invalid line while parsing alternate refs: %s",
+               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);