ref_remove_duplicates(): simplify loop logic
authorMichael Haggerty <mhagger@alum.mit.edu>
Wed, 30 Oct 2013 05:33:09 +0000 (06:33 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 Oct 2013 21:16:41 +0000 (14:16 -0700)
Change the loop body into the more straightforward

* remove item from the front of the old list
* if necessary, add it to the tail of the new list

and return a pointer to the new list (even though it is currently
always the same as the input argument, because the first element in
the list is currently never deleted).

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/fetch.c
remote.c
remote.h
index 5ddb9af05c107e09c453e2e4464c1075a9afec14..3d978eb58ec5cc1e2629db10562319c666bc031e 100644 (file)
@@ -360,9 +360,7 @@ static struct ref *get_ref_map(struct transport *transport,
                tail = &rm->next;
        }
 
-       ref_remove_duplicates(ref_map);
-
-       return ref_map;
+       return ref_remove_duplicates(ref_map);
 }
 
 #define STORE_REF_ERROR_OTHER 1
index 1fb87de01c6a3e7cede213b64a99408060eef33a..f803990760accb3e0d49dcde7c95965e326e6147 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -745,35 +745,45 @@ int for_each_remote(each_remote_fn fn, void *priv)
        return result;
 }
 
-void ref_remove_duplicates(struct ref *ref_map)
+struct ref *ref_remove_duplicates(struct ref *ref_map)
 {
        struct string_list refs = STRING_LIST_INIT_NODUP;
-       struct string_list_item *item = NULL;
-       struct ref *prev = NULL, *next = NULL;
+       struct ref *retval = NULL;
+       struct ref **p = &retval;
 
-       for (; ref_map; prev = ref_map, ref_map = next) {
-               next = ref_map->next;
-               if (!ref_map->peer_ref)
-                       continue;
+       while (ref_map) {
+               struct ref *ref = ref_map;
+
+               ref_map = ref_map->next;
+               ref->next = NULL;
 
-               item = string_list_insert(&refs, ref_map->peer_ref->name);
-               if (item->util) {
-                       /* Entry already existed */
-                       if (strcmp(((struct ref *)item->util)->name,
-                                  ref_map->name))
-                               die("%s tracks both %s and %s",
-                                   ref_map->peer_ref->name,
-                                   ((struct ref *)item->util)->name,
-                                   ref_map->name);
-                       prev->next = ref_map->next;
-                       free(ref_map->peer_ref);
-                       free(ref_map);
-                       ref_map = prev; /* skip this; we freed it */
+               if (!ref->peer_ref) {
+                       *p = ref;
+                       p = &ref->next;
                } else {
-                       item->util = ref_map;
+                       struct string_list_item *item =
+                               string_list_insert(&refs, ref->peer_ref->name);
+
+                       if (item->util) {
+                               /* Entry already existed */
+                               if (strcmp(((struct ref *)item->util)->name,
+                                          ref->name))
+                                       die("%s tracks both %s and %s",
+                                           ref->peer_ref->name,
+                                           ((struct ref *)item->util)->name,
+                                           ref->name);
+                               free(ref->peer_ref);
+                               free(ref);
+                       } else {
+                               *p = ref;
+                               p = &ref->next;
+                               item->util = ref;
+                       }
                }
        }
+
        string_list_clear(&refs, 0);
+       return retval;
 }
 
 int remote_has_url(struct remote *remote, const char *url)
index 131130a611b55c9f79649037e6dde916b621f578..c07eb9950a15600f7fde7faa60570ea5a558fb60 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -149,9 +149,13 @@ int resolve_remote_symref(struct ref *ref, struct ref *list);
 int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1);
 
 /*
- * Removes and frees any duplicate refs in the map.
+ * Remove and free all but the first of any entries in the input list
+ * that map the same remote reference to the same local reference.  If
+ * there are two entries that map different remote references to the
+ * same local reference, emit an error message and die.  Return a
+ * pointer to the head of the resulting list.
  */
-void ref_remove_duplicates(struct ref *ref_map);
+struct ref *ref_remove_duplicates(struct ref *ref_map);
 
 int valid_fetch_refspec(const char *refspec);
 struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec);