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 <mhag...@alum.mit.edu>
---
 builtin/fetch.c |  4 +---
 remote.c        | 52 +++++++++++++++++++++++++++++++---------------------
 remote.h        |  8 ++++++--
 3 files changed, 38 insertions(+), 26 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 5ddb9af..3d978eb 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -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
diff --git a/remote.c b/remote.c
index 15f3dc5..c90a2bf 100644
--- 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)
diff --git a/remote.h b/remote.h
index 131130a..c07eb99 100644
--- 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);
-- 
1.8.4.1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to