-1

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?

gkeenley
  • 6,088
  • 8
  • 54
  • 129

2 Answers2

1

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.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
1

To expand a bit on Mark Adelsberger's answer (which I've already upvoted): note that git clone means, in effect:

  1. 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.

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

  3. 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.

  4. Run any extra various git config commands needed as well.

  5. Run git fetch origin.

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

torek
  • 448,244
  • 59
  • 642
  • 775