when git can’t checkout a remote branch

Problem

Coworker has a workflow of:

  1. work on branch
  2. push branch and make PR of it
  3. delete local branch, checkout remote so that local is tracking remote
  4. carry on

except here’s what happened in the checkout stage:

user@host repo-name (master)$ git checkout issue-XXXXX-dummy-name-for-blogpost
 error: pathspec 'issue-XXXXX-dummy-name-for-blogpost' did not match any file(s) known to git.

It’s an old branch he’s trying to check out, but he just did the deletion step in this a few minutes ago. He does this all the time and he’s very experienced, so this was a bit of a pickle. I turned my rubber duckie over in my hands. We ran through some possibilities: doing a git fetch, trying it in a clean git clone (it worked fine), trying git-gc in the clone to see if it would break it, etc. Eventually, we turned to google.

Research

My search, yielded two stack overflow hits, and he told me about another.
They suggested checking git show-ref, and it we decided to diff the good and bad repo’s refs. The SO responses also turned up an explicit way to tell git to check out a remote branch locally and track it:

git fetch origin
git checkout -b test origin/test

His refs had something like the following in them:

bad repo:

user@host bad-repo-name (master)$ git show-ref
ddc955...0f61cb refs/remotes/experiment/issue-XXXXX-dummy-name-for-blogpost
86b183...ac388f refs/remotes/origin/issue-XXXXX-dummy-name-for-blogpost

good repo:

user@host good-repo-name (master)$ git show-ref
86b18399ad7cb01eeea74f5577c0a5dfe1ac388f refs/remotes/origin/issue-20198-remove-easy-cloud-accounting-copy

Solution

This led him to the realization that git must be doing some name-matching and hitting the first instance of the branch name. That ref line tells us that commit ddc955…0f61cb is ref’d as a branch with our name on a remote named ‘experiment’. The other line says that there is a different commit ref’d as a branch with our name on a remote named ‘origin’, which is what we want to check out.

Here’s the problem, and it was the aha moment: the ‘experiment’ remote no longer exists — this commit is old enough to have been used on a nascent form of this repo, when it was an experiment, moved from an existing svn repository. The issue is that the ‘experiment’ commit can’t be checked out, and git (reasonably) gives up at that point.

So he deleted the experiment branch and used the explicit form for checking out a branch from origin to track the remote. Problem solved.

Takeaway

For the future:

  • testing with a clean clone is really useful for determining if your problem is in your repo or everywhere
  • git show-refs is a reallllly useful tool for telling you all the things