Consider this test script.
#!/bin/sh -x
rm -rf origin clone
git init origin
cd origin
echo foo > file
git add -A
git commit -m "initial commit"
git branch foo
cd ..
git clone origin clone
cd clone
git rev-parse --verify foo
We create an origin
repo, create a branch named foo
, clone the repo, and in the clone, we attempt to validate that the name foo
is a valid object with git rev-parse --verify foo
.
But when I run this, it says, "fatal: Needed a single revision" which doesn't make any sense to me.
I guess it's trying to tell me that foo
isn't a branch name, that only origin/foo
exists? But it obviously works when I git checkout foo
.
Overall, what I'm trying to do is verify in advance that git checkout foo
will work, without actually running git checkout foo
. How would I do that?
You are correct: branch foo
does not exist in the clone.
The clone process normally copies all the branches—more precisely, references of the form refs/heads/*
—to remote-tracking branches, references of the form refs/remotes/<remote>/*
. (The name of the remote is whatever you specify with -o
, or origin
if you don't specify anything.)
After the clone completes, git clone
does a git checkout
of the branch you specify with -b
. If you don't specify something, it uses what it can see for HEAD
to decide what to git checkout
; most often, it just winds up doing git checkout master
.
It's that last git checkout master
step that actually creates the local branch master
, due to this bit from the git checkout
documentation:
If branch is not found but there does exist a tracking branch in exactly one remote (call it remote) with a matching name, treat as equivalent to
$ git checkout -b branch --track remote/branch
So if you're sure you've just git clone
d so that there is only one remote, and you know the name of the remote is origin
, you can simply do a git rev-parse --verify origin/foo
to find out if that remote-tracking branch exists. (Modify as needed for a differently-named remote; and/or, use git remote
to get a list of all possible remotes, then loop over all remotes to find out if there's exactly one branch named foo
, if needed.)
I'm not sure if this process is totally foolproof if some remote has weirdly-valued fetch =
lines, e.g., if remote origin
fetches into remote-tracking branches named refs/remotes/weird/master
instead of refs/remotes/origin/master
, it's possible that git checkout
will be OK with this, but if you check for origin/master
you won't find it. (On the other hand, weirdly-valued fetch =
lines will confuse other bits of git, including some code I was looking at in git pull
this morning.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With