d-_-b d-_-b - 3 years ago 151
Git Question

Git can not checkout another orphan branch from an orphan branch

On machine1 I create an orphan branch

git checkout --orphan branch1
.

On machine2 I cloned the repository with this one branch
git clone <url> --branch branch1 --single-branch
. This worked as expected.

Back on machine1 I created a new second orphan branch
git checkout --orphan branch2
.

On machine2 When I do
git fetch origin -- branch2
it responds with:


* branch branch2 -> FETCH_HEAD


But when I try to checkout the branch with
git checkout branch2
I see


error: pathspec 'branch2' did not match any file(s) known to git.


I can't figure out how to fetch and checkout the second orphan branch from my machine2. Is it because it started off as a
single-branch
clone?

Answer Source

First, a side note: an orphan branch is a branch with no parent and no commits. Since it has no commits, it doesn't exist. Once you make a commit on it, it's no longer an orphan: it has a commit, which can be a parent; it stops being an orphan branch at all. It is just an ordinary branch, just like every other branch. What is unusual about your repository is that it now has two (or more) root commits: commits that have no parent.

Since you were able to git fetch these things, they were not orphan branches; they were just branches. The "orphanness" (or lack thereof) is just a red herring.

What's going on

... When I do git fetch origin -- branch2

As PetSerAl noted in a comment, the refspec arguments to git fetch can, and often should, contain both a remote source part and a destination part:

git fetch origin src:dst

The source part can be abbreviated (as in branch2) or spelled out (refs/heads/branch2, so that you are quite certain you are getting a branch and not a tag or something). The destination part is normally a remote-tracking branch name (which is not a branch!) in your own repository, such as refs/remotes/origin/branch2.

The refspec can (and for remote-tracking branches, generally should) start with a plus sign, telling Git to overwrite your own reference regardless of what that means to you. For remote-tracking branch names, overwriting is sensible. For local branch names, it's much more questionable.

Normally you don't have to any of this

If you Git version is at least 1.8.4, git fetch normally figures all this out on its own. But single-branch clones are different:

Is it because it started off as a single-branch clone?

Yes! As a single-branch clone, your clone will have its default fetch refspec set to match just a single branch. That is, git fetch looks at your repository's configuration, and that configuration says: don't keep track of anything upstream except this one single branch.

You're trying to fetch a different branch, so your git fetch assumes you don't really want to keep track of it. It dumps the result into the temporary FETCH_HEAD file that every fetch always dumps everything into (for historical reasons among others) and then forgets it.

If you convert your single-branch clone to a normal clone, by editing the fetch = line to read the way it normally does, your now-normal clone will behave, well, normally. See How do I "undo" a --single-branch clone? for details (the accepted answer there assumes exactly one remote, named origin).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download