ref_remove_duplicates(): simplify loop logic

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>

Michael Haggerty committed Oct 30, 2013 at 06:33 UTC b9afe6654db2bfb776db933f832e7e03052adf98
3 files changed +38 -26
builtin/fetch.c
+1 -3
@@ -360,9 +360,7 @@ static struct ref *get_ref_map(struct transport *transport,
360 tail = &rm->next;
361 }
362
363 - ref_remove_duplicates(ref_map);
364 -
365 - return ref_map;
363 + return ref_remove_duplicates(ref_map);
364 }
365
366 #define STORE_REF_ERROR_OTHER 1
remote.c
+31 -21
@@ -745,35 +745,45 @@ int for_each_remote(each_remote_fn fn, void *priv)
745 return result;
746 }
747
748 -void ref_remove_duplicates(struct ref *ref_map)
748 +struct ref *ref_remove_duplicates(struct ref *ref_map)
749 {
750 struct string_list refs = STRING_LIST_INIT_NODUP;
751 - struct string_list_item *item = NULL;
752 - struct ref *prev = NULL, *next = NULL;
751 + struct ref *retval = NULL;
752 + struct ref **p = &retval;
753
754 - for (; ref_map; prev = ref_map, ref_map = next) {
755 - next = ref_map->next;
756 - if (!ref_map->peer_ref)
757 - continue;
754 + while (ref_map) {
755 + struct ref *ref = ref_map;
756 +
757 + ref_map = ref_map->next;
758 + ref->next = NULL;
759
759 - item = string_list_insert(&refs, ref_map->peer_ref->name);
760 - if (item->util) {
761 - /* Entry already existed */
762 - if (strcmp(((struct ref *)item->util)->name,
763 - ref_map->name))
764 - die("%s tracks both %s and %s",
765 - ref_map->peer_ref->name,
766 - ((struct ref *)item->util)->name,
767 - ref_map->name);
768 - prev->next = ref_map->next;
769 - free(ref_map->peer_ref);
770 - free(ref_map);
771 - ref_map = prev; /* skip this; we freed it */
760 + if (!ref->peer_ref) {
761 + *p = ref;
762 + p = &ref->next;
763 } else {
773 - item->util = ref_map;
764 + struct string_list_item *item =
765 + string_list_insert(&refs, ref->peer_ref->name);
766 +
767 + if (item->util) {
768 + /* Entry already existed */
769 + if (strcmp(((struct ref *)item->util)->name,
770 + ref->name))
771 + die("%s tracks both %s and %s",
772 + ref->peer_ref->name,
773 + ((struct ref *)item->util)->name,
774 + ref->name);
775 + free(ref->peer_ref);
776 + free(ref);
777 + } else {
778 + *p = ref;
779 + p = &ref->next;
780 + item->util = ref;
781 + }
782 }
783 }
784 +
785 string_list_clear(&refs, 0);
786 + return retval;
787 }
788
789 int remote_has_url(struct remote *remote, const char *url)
remote.h
+6 -2
@@ -149,9 +149,13 @@ int resolve_remote_symref(struct ref *ref, struct ref *list);
149 int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1);
150
151 /*
152 - * Removes and frees any duplicate refs in the map.
152 + * Remove and free all but the first of any entries in the input list
153 + * that map the same remote reference to the same local reference. If
154 + * there are two entries that map different remote references to the
155 + * same local reference, emit an error message and die. Return a
156 + * pointer to the head of the resulting list.
157 */
154 -void ref_remove_duplicates(struct ref *ref_map);
158 +struct ref *ref_remove_duplicates(struct ref *ref_map);
159
160 int valid_fetch_refspec(const char *refspec);
161 struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec);