Code

remote: let guess_remote_head() optionally return all matches
authorJay Soffian <jaysoffian@gmail.com>
Fri, 27 Feb 2009 19:10:05 +0000 (14:10 -0500)
committerJunio C Hamano <gitster@pobox.com>
Fri, 27 Feb 2009 23:08:17 +0000 (15:08 -0800)
Determining HEAD is ambiguous since it is done by comparing SHA1s.

In the case of multiple matches we return refs/heads/master if it
matches, else we return the first match we encounter. builtin-remote
needs all matches returned to it, so add a flag for it to request such.

To be simple and consistent, the return value is now a copy (including
peer_ref) of the matching refs.

Originally contributed by Jeff King along with the prior commit as a
single patch.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-clone.c
remote.c
remote.h

index f9ce4fbf19dd3d589eba9a1dd8afcc0e18ee320f..3146ca87f88e8f187c47b4a375c19b499c024b33 100644 (file)
@@ -510,7 +510,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                mapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf);
 
                remote_head = find_ref_by_name(refs, "HEAD");
-               head_points_at = guess_remote_head(remote_head, mapped_refs);
+               head_points_at = guess_remote_head(remote_head, mapped_refs, 0);
        }
        else {
                warning("You appear to have cloned an empty repository.");
index 22203ea8e2d00f6f3cfe3c883256685df0a01359..304e967e3c5068a9655fe8752e7c8331e9ac11f6 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -1460,24 +1460,33 @@ struct ref *get_local_heads(void)
        return local_refs;
 }
 
-const struct ref *guess_remote_head(const struct ref *head,
-                                   const struct ref *refs)
+struct ref *guess_remote_head(const struct ref *head,
+                             const struct ref *refs,
+                             int all)
 {
        const struct ref *r;
+       struct ref *list = NULL;
+       struct ref **tail = &list;
 
        if (!head)
                return NULL;
 
        /* If refs/heads/master could be right, it is. */
-       r = find_ref_by_name(refs, "refs/heads/master");
-       if (r && !hashcmp(r->old_sha1, head->old_sha1))
-               return r;
+       if (!all) {
+               r = find_ref_by_name(refs, "refs/heads/master");
+               if (r && !hashcmp(r->old_sha1, head->old_sha1))
+                       return copy_ref(r);
+       }
 
        /* Look for another ref that points there */
-       for (r = refs; r; r = r->next)
-               if (r != head && !hashcmp(r->old_sha1, head->old_sha1))
-                       return r;
+       for (r = refs; r; r = r->next) {
+               if (r != head && !hashcmp(r->old_sha1, head->old_sha1)) {
+                       *tail = copy_ref(r);
+                       tail = &((*tail)->next);
+                       if (!all)
+                               break;
+               }
+       }
 
-       /* Nothing is the same */
-       return NULL;
+       return list;
 }
index db49ce046704a5ebc65fb2929d46e20f15599a71..de3d21b6626f64ffc54904eec6f26a614feab30a 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -139,12 +139,14 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs);
 int format_tracking_info(struct branch *branch, struct strbuf *sb);
 
 struct ref *get_local_heads(void);
-
 /*
- * Look for a ref in refs whose SHA1 matches head, first checking if
- * refs/heads/master matches. Return NULL if nothing matches or if head
- * is NULL.
+ * Find refs from a list which are likely to be pointed to by the given HEAD
+ * ref. If 'all' is false, returns the most likely ref; otherwise, returns a
+ * list of all candidate refs. If no match is found (or 'head' is NULL),
+ * returns NULL. All returns are newly allocated and should be freed.
  */
-const struct ref *guess_remote_head(const struct ref *head,
-                                   const struct ref *refs);
+struct ref *guess_remote_head(const struct ref *head,
+                             const struct ref *refs,
+                             int all);
+
 #endif