I've cloned a single branch of a repo before using git clone -b <branch-name> <repo-name>
, but recently saw git clone --single-branch -b <branch-name> <repo-name>
being used.
What's the difference?
I've cloned a single branch of a repo before using git clone -b <branch-name> <repo-name>
, but recently saw git clone --single-branch -b <branch-name> <repo-name>
being used.
What's the difference?
The command you've used (git clone -b <branch-name> <repo-name>
) clones the entire repo. The only thing the -b
option does here is change what's initially checked out.
--single-branch
updates the default refspec so that only the specified branch's history (and related data) is downloaded.
To expand a bit on Mark Adelsberger's answer (which I've already upvoted): note that git clone
means, in effect:
Make a new totally-empty directory, or if directed, take over an existing totally-empty directory:
git clone https://github.com/git/git
will make new directory git
to hold the new Git repository. Enter this directory for the rest of these steps; but your command-line interpreter is not in the new directory, so after the clone finishes, you'll have to enter the new directory yourself.
Run git init
in this empty directory, so that it now has a .git
sub-directory to hold a Git repository. The new Git repository is totally empty (no commits, no branches, etc., although you're on the non-existent master
branch).
Run git remote add origin url
. For instance, for the above, Git would add a remote named origin
that tells Git to connect to https://github.com/git/git
.
Run any extra various git config
commands needed as well.
Run git fetch origin
.
Run git checkout branch
for some named branch
.
You can run these six steps manually, if you prefer, but git clone
is easier.
Now that you know what the six steps are, it's easy to explain both the -b
argument and the --single-branch
argument:
-b branch
selects the argument to pass to git checkout
in step 6. If you don't pick a branch name yourself, your Git will get a recommendation from their Git, during step 5, and will use that name.
--single-branch
adds a git config
command to step 4. In particular, it changes the remote.origin.fetch
setting.
The git remote add
step would / will set remote.origin.fetch
to +refs/heads/*:refs/remotes/origin/*
, which is an instruction to the git fetch
command—see step 5—to fetch all branches and rename all of them to your origin/*
remote-tracking names.
With --single-branch
, git clone
overrides the default. Instead of +refs/heads/*
, the left side of this refspec pair is +refs/heads/branch
. The right side is therefore +refs/remotes/origin/branch
, so that your final remote.origin.fetch
setting reads:
+refs/heads/<branch>:refs/remotes/origin/<branch>
which directs the git fetch
in step 5, and all future git fetch
operations, to update only your origin/branch
remote-tracking name.
Note that if you don't specifically select some branch in advance, git clone
will use whatever branch the other Git recommends in step 5, to achieve the step-4 configuration result. This means that in fact these steps aren't quite in order: git clone
just does each part internally wherever it's most convenient. If you want, for some reason, to do this manually, you'll need to do the six steps in this order. (You can use git remote add
with the -t
option to combine steps 3 and 4, though, as long as you don't need any other special configuration options due to other git clone
options.)