[PATCH v2 20/23] ref_remove_duplicates(): simplify loop logic

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]