Change fetch_pack() and friends to take string_list arguments

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@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Sep 9, 2012 at 08:19 UTC 8bee93dd24731a1d2ef7c82d484a893cf68b6572
3 files changed +51 -60
builtin/fetch-pack.c
+39 -49
@@ -525,27 +525,27 @@ static void mark_recent_complete_commits(unsigned long cutoff)
525 }
526 }
527
528 -static void filter_refs(struct ref **refs, int nr_match, char **match)
528 +static void filter_refs(struct ref **refs, struct string_list *sought)
529 {
530 struct ref **return_refs;
531 struct ref *newlist = NULL;
532 struct ref **newtail = &newlist;
533 struct ref *ref, *next;
534 struct ref *fastarray[32];
535 - int match_pos;
535 + int sought_pos;
536
537 - if (nr_match && !args.fetch_all) {
538 - if (ARRAY_SIZE(fastarray) < nr_match)
539 - return_refs = xcalloc(nr_match, sizeof(struct ref *));
537 + if (sought->nr && !args.fetch_all) {
538 + if (ARRAY_SIZE(fastarray) < sought->nr)
539 + return_refs = xcalloc(sought->nr, sizeof(struct ref *));
540 else {
541 return_refs = fastarray;
542 - memset(return_refs, 0, sizeof(struct ref *) * nr_match);
542 + memset(return_refs, 0, sizeof(struct ref *) * sought->nr);
543 }
544 }
545 else
546 return_refs = NULL;
547
548 - match_pos = 0;
548 + sought_pos = 0;
549 for (ref = *refs; ref; ref = next) {
550 next = ref->next;
551 if (!memcmp(ref->name, "refs/", 5) &&
@@ -560,17 +560,17 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
560 }
561 else {
562 int cmp = -1;
563 - while (match_pos < nr_match) {
564 - cmp = strcmp(ref->name, match[match_pos]);
563 + while (sought_pos < sought->nr) {
564 + cmp = strcmp(ref->name, sought->items[sought_pos].string);
565 if (cmp < 0) /* definitely do not have it */
566 break;
567 else if (cmp == 0) { /* definitely have it */
568 - match[match_pos][0] = '\0';
569 - return_refs[match_pos] = ref;
568 + sought->items[sought_pos].string[0] = '\0';
569 + return_refs[sought_pos] = ref;
570 break;
571 }
572 else /* might have it; keep looking */
573 - match_pos++;
573 + sought_pos++;
574 }
575 if (!cmp)
576 continue; /* we will link it later */
@@ -580,7 +580,7 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
580
581 if (!args.fetch_all) {
582 int i;
583 - for (i = 0; i < nr_match; i++) {
583 + for (i = 0; i < sought->nr; i++) {
584 ref = return_refs[i];
585 if (ref) {
586 *newtail = ref;
@@ -599,7 +599,7 @@ static void mark_alternate_complete(const struct ref *ref, void *unused)
599 mark_complete(NULL, ref->old_sha1, 0, NULL);
600 }
601
602 -static int everything_local(struct ref **refs, int nr_match, char **match)
602 +static int everything_local(struct ref **refs, struct string_list *sought)
603 {
604 struct ref *ref;
605 int retval;
@@ -650,7 +650,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
650 }
651 }
652
653 - filter_refs(refs, nr_match, match);
653 + filter_refs(refs, sought);
654
655 for (retval = 1, ref = *refs; ref ; ref = ref->next) {
656 const unsigned char *remote = ref->old_sha1;
@@ -781,8 +781,7 @@ static int get_pack(int xd[2], char **pack_lockfile)
781
782 static struct ref *do_fetch_pack(int fd[2],
783 const struct ref *orig_ref,
784 - int nr_match,
785 - char **match,
784 + struct string_list *sought,
785 char **pack_lockfile)
786 {
787 struct ref *ref = copy_ref_list(orig_ref);
@@ -839,7 +838,7 @@ static struct ref *do_fetch_pack(int fd[2],
838 agent_len, agent_feature);
839 }
840
842 - if (everything_local(&ref, nr_match, match)) {
841 + if (everything_local(&ref, sought)) {
842 packet_flush(fd[1]);
843 goto all_done;
844 }
@@ -859,16 +858,16 @@ static struct ref *do_fetch_pack(int fd[2],
858 return ref;
859 }
860
862 -static int remove_duplicates(int nr_heads, char **heads)
861 +static int remove_duplicates(struct string_list *sought)
862 {
863 int src, dst;
864
866 - if (!nr_heads)
865 + if (!sought->nr)
866 return 0;
867
869 - for (src = dst = 1; src < nr_heads; src++)
870 - if (strcmp(heads[src], heads[dst-1]))
871 - heads[dst++] = heads[src];
868 + for (src = dst = 1; src < sought->nr; src++)
869 + if (strcmp(sought->items[src].string, sought->items[dst-1].string))
870 + sought->items[dst++] = sought->items[src];
871 return dst;
872 }
873
@@ -922,8 +921,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
921 int i, ret;
922 struct ref *ref = NULL;
923 const char *dest = NULL;
925 - int alloc_heads = 0, nr_heads = 0;
926 - char **heads = NULL;
924 + struct string_list sought = STRING_LIST_INIT_DUP;
925 int fd[2];
926 char *pack_lockfile = NULL;
927 char **pack_lockfile_ptr = NULL;
@@ -1000,9 +998,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
998 * Copy refs from cmdline to growable list, then append any
999 * refs from the standard input:
1000 */
1003 - ALLOC_GROW(heads, argc - i, alloc_heads);
1001 for (; i < argc; i++)
1005 - heads[nr_heads++] = xstrdup(argv[i]);
1002 + string_list_append(&sought, xstrdup(argv[i]));
1003 if (args.stdin_refs) {
1004 if (args.stateless_rpc) {
1005 /* 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)
1012 break;
1013 if (line[n-1] == '\n')
1014 n--;
1018 - ALLOC_GROW(heads, nr_heads + 1, alloc_heads);
1019 - heads[nr_heads++] = xmemdupz(line, n);
1015 + string_list_append(&sought, xmemdupz(line, n));
1016 }
1017 }
1018 else {
1019 /* read from stdin one ref per line, until EOF */
1020 struct strbuf line = STRBUF_INIT;
1025 - while (strbuf_getline(&line, stdin, '\n') != EOF) {
1026 - ALLOC_GROW(heads, nr_heads + 1, alloc_heads);
1027 - heads[nr_heads++] = strbuf_detach(&line, NULL);
1028 - }
1021 + while (strbuf_getline(&line, stdin, '\n') != EOF)
1022 + string_list_append(&sought, strbuf_detach(&line, NULL));
1023 strbuf_release(&line);
1024 }
1025 }
@@ -1042,7 +1036,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
1036 get_remote_heads(fd[0], &ref, 0, NULL);
1037
1038 ref = fetch_pack(&args, fd, conn, ref, dest,
1045 - nr_heads, heads, pack_lockfile_ptr);
1039 + &sought, pack_lockfile_ptr);
1040 if (pack_lockfile) {
1041 printf("lock %s\n", pack_lockfile);
1042 fflush(stdout);
@@ -1053,17 +1047,19 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
1047 ref = NULL;
1048 ret = !ref;
1049
1056 - if (!ret && nr_heads) {
1050 + if (!ret && sought.nr) {
1051 /* If the heads to pull were given, we should have
1052 * consumed all of them by matching the remote.
1053 * Otherwise, 'git fetch remote no-such-ref' would
1054 * silently succeed without issuing an error.
1055 */
1062 - for (i = 0; i < nr_heads; i++)
1063 - if (heads[i] && heads[i][0]) {
1064 - error("no such remote ref %s", heads[i]);
1056 + for (i = 0; i < sought.nr; i++) {
1057 + char *s = sought.items[i].string;
1058 + if (s && s[0]) {
1059 + error("no such remote ref %s", s);
1060 ret = 1;
1061 }
1062 + }
1063 }
1064 while (ref) {
1065 printf("%s %s\n",
@@ -1074,17 +1070,11 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
1070 return ret;
1071 }
1072
1077 -static int compare_heads(const void *a, const void *b)
1078 -{
1079 - return strcmp(*(const char **)a, *(const char **)b);
1080 -}
1081 -
1073 struct ref *fetch_pack(struct fetch_pack_args *my_args,
1074 int fd[], struct child_process *conn,
1075 const struct ref *ref,
1076 const char *dest,
1086 - int nr_heads,
1087 - char **heads,
1077 + struct string_list *sought,
1078 char **pack_lockfile)
1079 {
1080 struct stat st;
@@ -1098,16 +1088,16 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
1088 st.st_mtime = 0;
1089 }
1090
1101 - if (heads && nr_heads) {
1102 - qsort(heads, nr_heads, sizeof(*heads), compare_heads);
1103 - nr_heads = remove_duplicates(nr_heads, heads);
1091 + if (sought->nr) {
1092 + sort_string_list(sought);
1093 + remove_duplicates(sought);
1094 }
1095
1096 if (!ref) {
1097 packet_flush(fd[1]);
1098 die("no matching remote head");
1099 }
1110 - ref_cpy = do_fetch_pack(fd, ref, nr_heads, heads, pack_lockfile);
1100 + ref_cpy = do_fetch_pack(fd, ref, sought, pack_lockfile);
1101
1102 if (args.depth > 0) {
1103 struct cache_time mtime;
fetch-pack.h
+3 -2
@@ -1,6 +1,8 @@
1 #ifndef FETCH_PACK_H
2 #define FETCH_PACK_H
3
4 +#include "string-list.h"
5 +
6 struct fetch_pack_args {
7 const char *uploadpack;
8 int unpacklimit;
@@ -21,8 +23,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
23 int fd[], struct child_process *conn,
24 const struct ref *ref,
25 const char *dest,
24 - int nr_heads,
25 - char **heads,
26 + struct string_list *sought,
27 char **pack_lockfile);
28
29 #endif
transport.c
+9 -9
@@ -518,8 +518,8 @@ static int fetch_refs_via_pack(struct transport *transport,
518 int nr_heads, struct ref **to_fetch)
519 {
520 struct git_transport_data *data = transport->data;
521 - char **heads = xmalloc(nr_heads * sizeof(*heads));
522 - char **origh = xmalloc(nr_heads * sizeof(*origh));
521 + struct string_list orig_sought = STRING_LIST_INIT_DUP;
522 + struct string_list sought = STRING_LIST_INIT_NODUP;
523 const struct ref *refs;
524 char *dest = xstrdup(transport->url);
525 struct fetch_pack_args args;
@@ -537,8 +537,10 @@ static int fetch_refs_via_pack(struct transport *transport,
537 args.no_progress = !transport->progress;
538 args.depth = data->options.depth;
539
540 - for (i = 0; i < nr_heads; i++)
541 - origh[i] = heads[i] = xstrdup(to_fetch[i]->name);
540 + for (i = 0; i < nr_heads; i++) {
541 + string_list_append(&orig_sought, to_fetch[i]->name);
542 + string_list_append(&sought, orig_sought.items[orig_sought.nr - 1].string);
543 + }
544
545 if (!data->got_remote_heads) {
546 connect_setup(transport, 0, 0);
@@ -548,7 +550,7 @@ static int fetch_refs_via_pack(struct transport *transport,
550
551 refs = fetch_pack(&args, data->fd, data->conn,
552 refs_tmp ? refs_tmp : transport->remote_refs,
551 - dest, nr_heads, heads, &transport->pack_lockfile);
553 + dest, &sought, &transport->pack_lockfile);
554 close(data->fd[0]);
555 close(data->fd[1]);
556 if (finish_connect(data->conn))
@@ -558,10 +560,8 @@ static int fetch_refs_via_pack(struct transport *transport,
560
561 free_refs(refs_tmp);
562
561 - for (i = 0; i < nr_heads; i++)
562 - free(origh[i]);
563 - free(origh);
564 - free(heads);
563 + string_list_clear(&sought, 0);
564 + string_list_clear(&orig_sought, 0);
565 free(dest);
566 return (refs ? 0 : -1);
567 }