Re: bug? in checkout with ambiguous refnames
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Jan 7, 2011, 19:44 UTC
- Message-ID
- <7vzkrc5wil.fsf@alter.siamese.dyndns.org>
- In-Reply-To
- <20110107104650.GA5399@pengutronix.de>
Uwe Kleine-König <u.kleine-koenig@pengutronix.de> writes:
> So working copy and cache are at refs/tags/sgu/mxs-amba-uart, HEAD > points to refs/heads/sgu/mxs-amba-uart
I somehow thought that we had an explicit logic to favor an exact branch name for "git checkout $branch" even when refs/something-other-than-head/$branch exists, while issuing the ambiguity warning.
Ahh, what this part of the code in builtin/checkout.c does is totally wrong:
/* we can't end up being in (2) anymore, eat the argument */ argv++; argc--;
new.name = arg;
if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
setup_branch_path(&new);if ((check_ref_format(new.path) == CHECK_REF_FORMAT_OK) && resolve_ref(new.path, rev, 1, NULL)) ; else new.path = NULL; parse_commit(new.commit); source_tree = new.commit->tree; } else source_tree = parse_tree_indirect(rev);
It uses lookup_commit_reference_gently() that follows the usual tags-then-heads preference order, but then uses setup_branch_path() to prefix the raw name with "refs/heads", which is totally backwards. It should do something like:
- use setup-branch-path to get refs/heads/$name
- check-ref-format and resolve it; if these fail, then we are detaching head at rev;
- otherwise, if the result of the resolution is not the same as rev, what we have in rev is incorrect (it was taken from the usual tags-then-heads rule but "checkout $name" must favor local branches). update the rev with the result of resolving refs/heads/$name
- parse new.commit out of rev. we are checking out the branch $name.