diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index 6cd734a9cb..12ba009c12 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -525,6 +525,16 @@ static void mark_recent_complete_commits(unsigned long cutoff) } } +static int non_matching_ref(struct string_list_item *item, void *unused) +{ + if (item->util) { + item->util = NULL; + return 0; + } + else + return 1; +} + static void filter_refs(struct ref **refs, struct string_list *sought) { struct ref **return_refs; @@ -566,7 +576,7 @@ static void filter_refs(struct ref **refs, struct string_list *sought) break; else if (cmp == 0) { /* definitely have it */ return_refs[sought_pos] = ref; - sought->items[sought_pos++].string[0] = '\0'; + sought->items[sought_pos++].util = "matched"; break; } else /* might have it; keep looking */ @@ -590,6 +600,7 @@ static void filter_refs(struct ref **refs, struct string_list *sought) } if (return_refs != fastarray) free(return_refs); + filter_string_list(sought, 0, non_matching_ref, NULL); } *refs = newlist; } @@ -1040,13 +1051,9 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) * Otherwise, 'git fetch remote no-such-ref' would * silently succeed without issuing an error. */ - for (i = 0; i < sought.nr; i++) { - char *s = sought.items[i].string; - if (s && s[0]) { - error("no such remote ref %s", s); - ret = 1; - } - } + for (i = 0; i < sought.nr; i++) + error("no such remote ref %s", sought.items[i].string); + ret = 1; } while (ref) { printf("%s %s\n", diff --git a/fetch-pack.h b/fetch-pack.h index a6a8a73311..cb148719bf 100644 --- a/fetch-pack.h +++ b/fetch-pack.h @@ -19,6 +19,13 @@ struct fetch_pack_args { stateless_rpc:1; }; +/* + * sought contains the full names of remote references that should be + * updated from. On return, the names that were found on the remote + * will have been removed from the list. The util members of the + * string_list_items are used internally; they must be NULL on entry + * (and will be NULL on exit). + */ struct ref *fetch_pack(struct fetch_pack_args *args, int fd[], struct child_process *conn, const struct ref *ref, diff --git a/transport.c b/transport.c index a847bf31e2..9932f402df 100644 --- a/transport.c +++ b/transport.c @@ -518,8 +518,7 @@ static int fetch_refs_via_pack(struct transport *transport, int nr_heads, struct ref **to_fetch) { struct git_transport_data *data = transport->data; - struct string_list orig_sought = STRING_LIST_INIT_DUP; - struct string_list sought = STRING_LIST_INIT_NODUP; + struct string_list sought = STRING_LIST_INIT_DUP; const struct ref *refs; char *dest = xstrdup(transport->url); struct fetch_pack_args args; @@ -537,10 +536,8 @@ static int fetch_refs_via_pack(struct transport *transport, args.no_progress = !transport->progress; args.depth = data->options.depth; - for (i = 0; i < nr_heads; i++) { - string_list_append(&orig_sought, to_fetch[i]->name); - string_list_append(&sought, orig_sought.items[orig_sought.nr - 1].string); - } + for (i = 0; i < nr_heads; i++) + string_list_append(&sought, to_fetch[i]->name); if (!data->got_remote_heads) { connect_setup(transport, 0, 0); @@ -561,7 +558,6 @@ static int fetch_refs_via_pack(struct transport *transport, free_refs(refs_tmp); string_list_clear(&sought, 0); - string_list_clear(&orig_sought, 0); free(dest); return (refs ? 0 : -1); }