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);