filter_refs(): delete matched refs from sought list
authorMichael Haggerty <mhagger@alum.mit.edu>
Sun, 9 Sep 2012 06:19:43 +0000 (08:19 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 12 Sep 2012 18:46:31 +0000 (11:46 -0700)
Remove any references that are available from the remote from the
sought list (rather than overwriting their names with NUL characters,
as previously).  Mark matching entries by writing a non-NULL pointer
to string_list_item::util during the iteration, then use
filter_string_list() later to filter out the entries that have been
marked.

Document this aspect of fetch_pack() in a comment in the header file.
(More documentation is obviously still needed.)

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/fetch-pack.c
fetch-pack.h
transport.c

index 6cd734a9cbf583b56488bc5828c68f8a3536b240..12ba009c12911f463ba0ff1e1de3a7b62b4a3f4c 100644 (file)
@@ -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",
index a6a8a733112d3de0c77a60bd7114489cce0579d9..cb148719bfd3bace27a0ca9611f1c38066fb6ed4 100644 (file)
@@ -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,
index a847bf31e23e9ad0dbc565326cfc21a7cddcc5f5..9932f402dfee2605dbb498b120813aebaa3961f8 100644 (file)
@@ -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);
 }