fetch-pack: report missing refs even if no existing refs were received
[gitweb.git] / builtin / fetch-pack.c
index 6cd734a9cbf583b56488bc5828c68f8a3536b240..3d388b53e3b52be1757146de9e72ba3d81c51673 100644 (file)
@@ -525,72 +525,59 @@ 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;
        struct ref *newlist = NULL;
        struct ref **newtail = &newlist;
        struct ref *ref, *next;
-       struct ref *fastarray[32];
        int sought_pos;
 
-       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 *) * sought->nr);
-               }
-       }
-       else
-               return_refs = NULL;
-
        sought_pos = 0;
        for (ref = *refs; ref; ref = next) {
+               int keep = 0;
                next = ref->next;
                if (!memcmp(ref->name, "refs/", 5) &&
                    check_refname_format(ref->name + 5, 0))
                        ; /* trash */
                else if (args.fetch_all &&
-                        (!args.depth || prefixcmp(ref->name, "refs/tags/") )) {
-                       *newtail = ref;
-                       ref->next = NULL;
-                       newtail = &ref->next;
-                       continue;
-               }
+                        (!args.depth || prefixcmp(ref->name, "refs/tags/")))
+                       keep = 1;
                else {
-                       int cmp = -1;
                        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 */
-                                       return_refs[sought_pos] = ref;
-                                       sought->items[sought_pos++].string[0] = '\0';
+                               int cmp = strcmp(ref->name, sought->items[sought_pos].string);
+                               if (cmp < 0)
+                                       break; /* definitely do not have it */
+                               else if (cmp == 0) {
+                                       keep = 1; /* definitely have it */
+                                       sought->items[sought_pos++].util = "matched";
                                        break;
                                }
-                               else /* might have it; keep looking */
-                                       sought_pos++;
+                               else
+                                       sought_pos++; /* might have it; keep looking */
                        }
-                       if (!cmp)
-                               continue; /* we will link it later */
                }
-               free(ref);
-       }
 
-       if (!args.fetch_all) {
-               int i;
-               for (i = 0; i < sought->nr; i++) {
-                       ref = return_refs[i];
-                       if (ref) {
-                               *newtail = ref;
-                               ref->next = NULL;
-                               newtail = &ref->next;
-                       }
+               if (keep) {
+                       *newtail = ref;
+                       ref->next = NULL;
+                       newtail = &ref->next;
+               } else {
+                       free(ref);
                }
-               if (return_refs != fastarray)
-                       free(return_refs);
        }
+
+       if (!args.fetch_all)
+               filter_string_list(sought, 0, non_matching_ref, NULL);
        *refs = newlist;
 }
 
@@ -1031,22 +1018,18 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
        close(fd[0]);
        close(fd[1]);
        if (finish_connect(conn))
-               ref = NULL;
-       ret = !ref;
+               return 1;
 
-       if (!ret && sought.nr) {
+       ret = !ref;
+       if (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 < 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",