Instead of juggling <nr_heads,heads> (sometimes called <nr_match,match>), pass around the list of references to be sought in a single string_list variable called "sought". Future commits will make more use of string_list functionality. Signed-off-by: Michael Haggerty <mhagger@xxxxxxxxxxxx> --- builtin/fetch-pack.c | 88 +++++++++++++++++++++++----------------------------- fetch-pack.h | 5 +-- transport.c | 18 +++++------ 3 files changed, 51 insertions(+), 60 deletions(-) diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index 30990c0..df81995 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -525,27 +525,27 @@ static void mark_recent_complete_commits(unsigned long cutoff) } } -static void filter_refs(struct ref **refs, int nr_match, char **match) +static void filter_refs(struct ref **refs, struct string_list *sought) { struct ref **return_refs; struct ref *newlist = NULL; struct ref **newtail = &newlist; struct ref *ref, *next; struct ref *fastarray[32]; - int match_pos; + int sought_pos; - if (nr_match && !args.fetch_all) { - if (ARRAY_SIZE(fastarray) < nr_match) - return_refs = xcalloc(nr_match, sizeof(struct ref *)); + if (sought->nr && !args.fetch_all) { + if (ARRAY_SIZE(fastarray) < sought->nr) + return_refs = xcalloc(sought->nr, sizeof(struct ref *)); else { return_refs = fastarray; - memset(return_refs, 0, sizeof(struct ref *) * nr_match); + memset(return_refs, 0, sizeof(struct ref *) * sought->nr); } } else return_refs = NULL; - match_pos = 0; + sought_pos = 0; for (ref = *refs; ref; ref = next) { next = ref->next; if (!memcmp(ref->name, "refs/", 5) && @@ -560,17 +560,17 @@ static void filter_refs(struct ref **refs, int nr_match, char **match) } else { int cmp = -1; - while (match_pos < nr_match) { - cmp = strcmp(ref->name, match[match_pos]); + while (sought_pos < sought->nr) { + cmp = strcmp(ref->name, sought->items[sought_pos].string); if (cmp < 0) /* definitely do not have it */ break; else if (cmp == 0) { /* definitely have it */ - match[match_pos][0] = '\0'; - return_refs[match_pos] = ref; + sought->items[sought_pos].string[0] = '\0'; + return_refs[sought_pos] = ref; break; } else /* might have it; keep looking */ - match_pos++; + sought_pos++; } if (!cmp) continue; /* we will link it later */ @@ -580,7 +580,7 @@ static void filter_refs(struct ref **refs, int nr_match, char **match) if (!args.fetch_all) { int i; - for (i = 0; i < nr_match; i++) { + for (i = 0; i < sought->nr; i++) { ref = return_refs[i]; if (ref) { *newtail = ref; @@ -599,7 +599,7 @@ static void mark_alternate_complete(const struct ref *ref, void *unused) mark_complete(NULL, ref->old_sha1, 0, NULL); } -static int everything_local(struct ref **refs, int nr_match, char **match) +static int everything_local(struct ref **refs, struct string_list *sought) { struct ref *ref; int retval; @@ -650,7 +650,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match) } } - filter_refs(refs, nr_match, match); + filter_refs(refs, sought); for (retval = 1, ref = *refs; ref ; ref = ref->next) { const unsigned char *remote = ref->old_sha1; @@ -781,8 +781,7 @@ static int get_pack(int xd[2], char **pack_lockfile) static struct ref *do_fetch_pack(int fd[2], const struct ref *orig_ref, - int nr_match, - char **match, + struct string_list *sought, char **pack_lockfile) { struct ref *ref = copy_ref_list(orig_ref); @@ -839,7 +838,7 @@ static struct ref *do_fetch_pack(int fd[2], agent_len, agent_feature); } - if (everything_local(&ref, nr_match, match)) { + if (everything_local(&ref, sought)) { packet_flush(fd[1]); goto all_done; } @@ -859,16 +858,16 @@ static struct ref *do_fetch_pack(int fd[2], return ref; } -static int remove_duplicates(int nr_heads, char **heads) +static int remove_duplicates(struct string_list *sought) { int src, dst; - if (!nr_heads) + if (!sought->nr) return 0; - for (src = dst = 1; src < nr_heads; src++) - if (strcmp(heads[src], heads[dst-1])) - heads[dst++] = heads[src]; + for (src = dst = 1; src < sought->nr; src++) + if (strcmp(sought->items[src].string, sought->items[dst-1].string)) + sought->items[dst++] = sought->items[src]; return dst; } @@ -922,8 +921,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) int i, ret; struct ref *ref = NULL; const char *dest = NULL; - int alloc_heads = 0, nr_heads = 0; - char **heads = NULL; + struct string_list sought = STRING_LIST_INIT_DUP; int fd[2]; char *pack_lockfile = NULL; char **pack_lockfile_ptr = NULL; @@ -1000,9 +998,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) * Copy refs from cmdline to growable list, then append any * refs from the standard input: */ - ALLOC_GROW(heads, argc - i, alloc_heads); for (; i < argc; i++) - heads[nr_heads++] = xstrdup(argv[i]); + string_list_append(&sought, xstrdup(argv[i])); if (args.stdin_refs) { if (args.stateless_rpc) { /* in stateless RPC mode we use pkt-line to read @@ -1015,17 +1012,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) break; if (line[n-1] == '\n') n--; - ALLOC_GROW(heads, nr_heads + 1, alloc_heads); - heads[nr_heads++] = xmemdupz(line, n); + string_list_append(&sought, xmemdupz(line, n)); } } else { /* read from stdin one ref per line, until EOF */ struct strbuf line = STRBUF_INIT; - while (strbuf_getline(&line, stdin, '\n') != EOF) { - ALLOC_GROW(heads, nr_heads + 1, alloc_heads); - heads[nr_heads++] = strbuf_detach(&line, NULL); - } + while (strbuf_getline(&line, stdin, '\n') != EOF) + string_list_append(&sought, strbuf_detach(&line, NULL)); strbuf_release(&line); } } @@ -1042,7 +1036,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) get_remote_heads(fd[0], &ref, 0, NULL); ref = fetch_pack(&args, fd, conn, ref, dest, - nr_heads, heads, pack_lockfile_ptr); + &sought, pack_lockfile_ptr); if (pack_lockfile) { printf("lock %s\n", pack_lockfile); fflush(stdout); @@ -1053,17 +1047,19 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) ref = NULL; ret = !ref; - if (!ret && nr_heads) { + if (!ret && sought.nr) { /* If the heads to pull were given, we should have * consumed all of them by matching the remote. * Otherwise, 'git fetch remote no-such-ref' would * silently succeed without issuing an error. */ - for (i = 0; i < nr_heads; i++) - if (heads[i] && heads[i][0]) { - error("no such remote ref %s", heads[i]); + 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; } + } } while (ref) { printf("%s %s\n", @@ -1074,17 +1070,11 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) return ret; } -static int compare_heads(const void *a, const void *b) -{ - return strcmp(*(const char **)a, *(const char **)b); -} - struct ref *fetch_pack(struct fetch_pack_args *my_args, int fd[], struct child_process *conn, const struct ref *ref, const char *dest, - int nr_heads, - char **heads, + struct string_list *sought, char **pack_lockfile) { struct stat st; @@ -1098,16 +1088,16 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args, st.st_mtime = 0; } - if (heads && nr_heads) { - qsort(heads, nr_heads, sizeof(*heads), compare_heads); - nr_heads = remove_duplicates(nr_heads, heads); + if (sought->nr) { + sort_string_list(sought); + remove_duplicates(sought); } if (!ref) { packet_flush(fd[1]); die("no matching remote head"); } - ref_cpy = do_fetch_pack(fd, ref, nr_heads, heads, pack_lockfile); + ref_cpy = do_fetch_pack(fd, ref, sought, pack_lockfile); if (args.depth > 0) { struct cache_time mtime; diff --git a/fetch-pack.h b/fetch-pack.h index 1dbe90f..a6a8a73 100644 --- a/fetch-pack.h +++ b/fetch-pack.h @@ -1,6 +1,8 @@ #ifndef FETCH_PACK_H #define FETCH_PACK_H +#include "string-list.h" + struct fetch_pack_args { const char *uploadpack; int unpacklimit; @@ -21,8 +23,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args, int fd[], struct child_process *conn, const struct ref *ref, const char *dest, - int nr_heads, - char **heads, + struct string_list *sought, char **pack_lockfile); #endif diff --git a/transport.c b/transport.c index 1811b50..a847bf3 100644 --- a/transport.c +++ b/transport.c @@ -518,8 +518,8 @@ static int fetch_refs_via_pack(struct transport *transport, int nr_heads, struct ref **to_fetch) { struct git_transport_data *data = transport->data; - char **heads = xmalloc(nr_heads * sizeof(*heads)); - char **origh = xmalloc(nr_heads * sizeof(*origh)); + struct string_list orig_sought = STRING_LIST_INIT_DUP; + struct string_list sought = STRING_LIST_INIT_NODUP; const struct ref *refs; char *dest = xstrdup(transport->url); struct fetch_pack_args args; @@ -537,8 +537,10 @@ 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++) - origh[i] = heads[i] = xstrdup(to_fetch[i]->name); + 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); + } if (!data->got_remote_heads) { connect_setup(transport, 0, 0); @@ -548,7 +550,7 @@ static int fetch_refs_via_pack(struct transport *transport, refs = fetch_pack(&args, data->fd, data->conn, refs_tmp ? refs_tmp : transport->remote_refs, - dest, nr_heads, heads, &transport->pack_lockfile); + dest, &sought, &transport->pack_lockfile); close(data->fd[0]); close(data->fd[1]); if (finish_connect(data->conn)) @@ -558,10 +560,8 @@ static int fetch_refs_via_pack(struct transport *transport, free_refs(refs_tmp); - for (i = 0; i < nr_heads; i++) - free(origh[i]); - free(origh); - free(heads); + string_list_clear(&sought, 0); + string_list_clear(&orig_sought, 0); free(dest); return (refs ? 0 : -1); } -- 1.7.11.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html