On Fri, Jun 21, 2019 at 10:16 PM Junio C Hamano <gitster@xxxxxxxxx> wrote: > > Kyle Meyer <kyle@xxxxxxxxxx> writes: > > >> git rev-parse "${BRANCH_NAME}" || git rev-parse "refs/remotes/${UPSTREAM}/${BRANCH_NAME}" > >> > >> Unfortunately somebody used the branch name "add-gcc10" and `git rev-parse` which didn't exist on one repository. However `git rev-parse` > >> also supports to parse the `git-describe` format which resulted in checkout a commit starting with "cc10". I wonder if something like refs/heads/foo-g<hash> could trip the parser and mistake it as a `git-describe` output. Staring at get_describe_name() alone the answer might be an unfortunate "yes". But maybe something will kick in earlier and reject it. > > > > Can't you prepend "refs/heads/" to BRANCH_NAME to disambiguate? > > Yes, that is the kosher way for most commands. Some commands always prepend refs/heads/ to the <branch> argument you give it if I remember correctly. Or I think I accidentally made refs/heads/refs/heads/something once with some command (then hell ensued). If true, prepending refs/heads/ is not really foolproof. > It gets a bit tricky for "checkout <branch-or-committish>" that > changes its behaviour (a local branch is checked out and the next > commit extends it, other committishes like tags and remote-tracking > branch tips are checked out on a detached HEAD), and has special > rules for a "${BRANCH_NAME}" that is both the name of a local branch > and something else. I think "git checkout --no-guess --no-detach <branch>" should only accept a branch (i.e. ref: refs/heads/<branch>). Dropping --no-detach should allow any ref, which interprets refs/heads/foo as an absolute ref, not as refs/heads/refs/heads/foo. > Hopefully (Duy Cc'ed) "git switch" would improve the situation. "git switch" has slightly saner defaults, but with --guess being default to be friendlier to interactive usage, it's still not that much friendlier to scripts, unfortunately. -- Duy