Skip to content

Commit b9afe66

Browse files
mhaggergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2071e05 commit b9afe66

File tree

3 files changed

+38
-26
lines changed

3 files changed

+38
-26
lines changed

builtin/fetch.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,7 @@ static struct ref *get_ref_map(struct transport *transport,
360360
tail = &rm->next;
361361
}
362362

363-
ref_remove_duplicates(ref_map);
364-
365-
return ref_map;
363+
return ref_remove_duplicates(ref_map);
366364
}
367365

368366
#define STORE_REF_ERROR_OTHER 1

remote.c

+31-21
Original file line numberDiff line numberDiff line change
@@ -745,35 +745,45 @@ int for_each_remote(each_remote_fn fn, void *priv)
745745
return result;
746746
}
747747

748-
void ref_remove_duplicates(struct ref *ref_map)
748+
struct ref *ref_remove_duplicates(struct ref *ref_map)
749749
{
750750
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;
753753

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

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;
772763
} 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+
}
774782
}
775783
}
784+
776785
string_list_clear(&refs, 0);
786+
return retval;
777787
}
778788

779789
int remote_has_url(struct remote *remote, const char *url)

remote.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,13 @@ int resolve_remote_symref(struct ref *ref, struct ref *list);
149149
int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1);
150150

151151
/*
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.
153157
*/
154-
void ref_remove_duplicates(struct ref *ref_map);
158+
struct ref *ref_remove_duplicates(struct ref *ref_map);
155159

156160
int valid_fetch_refspec(const char *refspec);
157161
struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec);

0 commit comments

Comments
 (0)