Skip to content

Commit

Permalink
remote: let guess_remote_head() optionally return all matches
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jay Soffian authored and Junio C Hamano committed Feb 27, 2009
1 parent 7b3db09 commit 4229f1f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
2 changes: 1 addition & 1 deletion builtin-clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down
29 changes: 19 additions & 10 deletions remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
14 changes: 8 additions & 6 deletions remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 4229f1f

Please sign in to comment.