Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git rev-parse --verify says "fatal: Needed a single revision"

Tags:

git

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?

like image 409
Dan Fabulich Avatar asked Feb 05 '15 23:02

Dan Fabulich


1 Answers

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 cloned 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.)

like image 64
torek Avatar answered Oct 26 '22 17:10

torek