Problem
Coworker has a workflow of:
- work on branch
- push branch and make PR of it
- delete local branch, checkout remote so that local is tracking remote
- 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