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>
This commit is contained in:
Michael Haggerty 2013-10-30 06:33:09 +01:00 коммит произвёл Junio C Hamano
Родитель 2071e05ed2
Коммит b9afe6654d
3 изменённых файлов: 38 добавлений и 26 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
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 */
ref_map = ref_map->next;
ref->next = NULL;
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)

Просмотреть файл

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