Uwe Kleine-KÃnig <u.kleine-koenig@xxxxxxxxxxxxxx> 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. -- 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