How do I clone a single branch in Git?
I have a local Git repository in ~/local_repo
. It has a few branches:
$ git branch
* master
rails
c
c++
To clone the local repository, I do:
$ git clone ~/local_repo new_repo
Initialized empty Git repository in /home/username/new_repo/.git/
The n开发者_运维问答ew_repo
master branch points to the local_repo
master branch, and I can push / pull.
But I am unable to clone another branch. I want to only pull the branch I want (e.g. rails
), so that the new repository has a master
branch that pushes to and pulls from local_repo
's rails
branch, by default. How do I accomplish this, or perhaps something similar with local_repo
tracking the master local_repo
?
Note: the git1.7.10 (April 2012) actually allows you to clone only one branch:
# clone only the remote primary HEAD (default: origin/master)
git clone <url> --single-branch
# as in:
git clone <url> --branch <branch> --single-branch <folder>
Note:
<url>
is the URL of the remote repository, and does not reference the branch cloned<folder>
is the local folder where you want to clone the repository
You can see it in t5500-fetch-pack.sh
:
test_expect_success 'single branch clone' '
git clone --single-branch "file://$(pwd)/." singlebranch
'
Tobu comments that:
This is implicit when doing a shallow clone.
This makesgit clone --depth 1
the easiest way to save bandwidth.
And since Git 1.9.0 (February 2014), shallow clones support data transfer (push/pull), so that option is even more useful now.
See more at "Is git clone --depth 1
(shallow clone) more useful than it makes out?".
"Undoing" a shallow clone is detailed at "Convert shallow clone to full clone" (git 1.8.3+)
# unshallow the current branch
git fetch --unshallow
# for getting back all the branches (see Peter Cordes' comment)
git config remote.origin.fetch refs/heads/*:refs/remotes/origin/*
git fetch --unshallow
As Chris comments:
the magic line for getting missing branches to reverse
--single-branch
is (git v2.1.4):
git config remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
git fetch --unshallow
With Git 2.26 (Q1 2020), "git clone --recurse-submodules --single-branch
" now uses the same single-branch option when cloning the submodules.
See commit 132f600, commit 4731957 (21 Feb 2020) by Emily Shaffer (nasamuffin
).
(Merged by Junio C Hamano -- gitster
-- in commit b22db26, 05 Mar 2020)
clone
: pass --single-branch during --recurse-submodulesSigned-off-by: Emily Shaffer
Acked-by: Jeff KingPreviously, performing "
git clone --recurse-submodules --single-branch
" resulted in submodules cloning all branches even though the superproject cloned only one branch.Pipe
--single-branch
through the submodule helper framework to make it to 'clone
' later on.
One way is to execute the following.
git clone user@git-server:project_name.git -b branch_name /your/folder
Where branch_name
is the branch of your choice and "/your/folder" is the destination folder for that branch. It's true that this will bring other branches giving you the opportunity to merge back and forth.
Update
Now, starting with Git 1.7.10, you can now do this
git clone user@git-server:project_name.git -b branch_name --single-branch /your/folder
Using Git version 1.7.3.1 (on Windows), here's what I do ($BRANCH
is the name of the branch I want to checkout and $REMOTE_REPO
is the URL of the remote repository I want to clone from):
mkdir $BRANCH
cd $BRANCH
git init
git remote add -t $BRANCH -f origin $REMOTE_REPO
git checkout $BRANCH
The advantage of this approach is that subsequent git pull
(or git fetch
) calls will also just download the requested branch.
You can try the long-winded way:
mkdir newrepo.git
cd newrepo.git
git init
git remote add origin file:///path/to/original
git fetch origin branchiwant:refs/remotes/origin/branchiwant
git checkout -b branchiwant --track origin/branchiwant
What this does is:
- Create and init an empty Git repository.
- Adds the original repository as a remote called origin.
- Fetches only the branch you require from the remote called origin.
- Creates and checks out a new branch that is set up to track the source branch you just cloned.
Hopefully that will be something like what you are after.
git clone <url> --branch <branch> --single-branch
Just put in URL and branch name.
You can do it by using the below command:
git clone -b branch_name --single-branch project_url local_folder_to_clone_in
From git-clone man page:
--single-branch
is your friend during clone
remember to use with --branch <branch name>
or only remote primary HEAD will be cloned (master by default)
Always remember to do Ctrl + F5 to read fresh source, not the one from cache :-) (I didn't so didn't know about this option for long time.)
Clone only one branch. This is the easiest way:
git clone -b BRANCH_NAME --single-branch git@bitbucket.org:___/PROJECTNAME.git
There are ample answers here which mention:
Download 1 branch (with the
--single-branch
part):# (We'll refer to this as "the 1st command" below.) # 1. Clone ONLY `branch_name`, then check it out. The `--single-branch` part # means that ONLY `branch_name` is cloned, fetched, pulled, and # tracked. _No other remote branches will be cloned to your PC # whatsoever._ git clone -b branch_name --single-branch \ https://github.com/some_project/some_project.git
...or some version of that, and a few which mention just:
Download all branches (withOUT the
--single-branch
part):# (We'll refer to this as "the 2nd command" below.) # 2. Clone ALL remote branches, then `git checkout` the `branch_name` # branch. git clone -b branch_name \ https://github.com/some_project/some_project.git
But, I'd like to expound upon these two things a bit and show a more familiar set of equivalent commands so we can see what is happening with each under-the-hood.
Let's assume that you have a remote repo on GitHub at https://github.com/micronucleus/micronucleus.git, with remote branches master
and version_2.5
(this is a real example you can actually run right now).
Breakdown of the 2nd command from above:
The 2nd command (git clone -b version_2.5 https://github.com/micronucleus/micronucleus.git
) clones ALL REMOTE BRANCHES to your local PC, but then checks out the version_2.5
branch instead of the master
branch. That one command is the equivalent of doing this:
git clone https://github.com/micronucleus/micronucleus.git
cd micronucleus # cd into the repo you just cloned
git checkout version_2.5
# To be pedantic, also delete the local `master` branch since
# technically it won't exist yet since you haven't yet checked
# it out with `git checkout master`, which would create it from
# your locally-stored remote-tracking branch, `origin/master`
git branch -d master
The -b version_2.5
part automatically checked out the version_2.5
branch for us instead of master
.
git branch -a
shows us that ALL branches, however, were cloned to our local PC. Here you can see our local branch version_2.5
, which we are on, plus the locally-stored remote-tracking branches origin/HEAD
(which points to origin/master
), plus origin/master
, and origin/version_2.5
:
$ git branch -a
* version_2.5
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/version_2.5
We can also look at what our fetch
references are. You can either open up the .git/config
file to see them directly, or just run git config remote.origin.fetch
:
$ git config remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
You can see above that our git fetch
command (which is also triggered by git pull
since that is equivalent to git fetch && git merge
) is configured to fetch ALL heads for ALL branches in the origin
remote. I'm not an expert on this part, but I believe that's what +refs/heads/*:refs/remotes/origin/*
means.
Breakdown of the 1st command from above:
The 1st command (git clone -b version_2.5 --single-branch https://github.com/micronucleus/micronucleus.git
) clones ONLY the version_2.5
branch to your local PC, and it also checks it out. That one command is the equivalent of doing this (in the end result at least, except that it also downloads much less data in the beginning since it only clones ONE branch NOT all of them):
git clone https://github.com/micronucleus/micronucleus.git
cd micronucleus # cd into the repo you just cloned
git checkout version_2.5
# Delete ALL other branches, including remote-tracking ones, which are not the
# `version_2.5` branch:
# One local branch
git branch -d master
# ALL other locally-stored remote-tracking branches
git branch -dr origin/HEAD
git branch -dr origin/master
# Fix your `.git/config` file so that `git fetch` does the right thing, fetching
# ONLY the `version_2.5` branch head from the `origin/version_2.5` remote branch:
git config remote.origin.fetch \
"+refs/heads/version_2.5:refs/remotes/origin/version_2.5"
The -b version_2.5
part caused the version_2.5
branch to be checked out instead of the master
branch by default (as previously explained above), and the --single-branch
part caused:
- NONE of the other branches to be cloned to our PC, and
git fetch
to be configured such that NONE of the other branches will ever be fetched when we callgit fetch
orgit pull
!
This command truly cloned and will fetch only the one branch we wanted, and that's it!
git branch -a
shows us that ONLY the version_2.5
branch was cloned and checked out. Here we see by the *
which branch is checked-out, and we see also that we have a locally-stored remote-tracking branch for origin/version_2.5
:
$ git branch -a
* version_2.5
remotes/origin/version_2.5
We can also look at what our fetch
references are. You can either open up the .git/config
file to see them directly, or just run git config remote.origin.fetch
:
$ git config remote.origin.fetch
+refs/heads/version_2.5:refs/remotes/origin/version_2.5
You can see above that our git fetch
command will only fetch the version_2.5
branch head from the origin/version_2.5
remote branch. That's it! Beware that no other remote branches will ever be fetched.
Summary:
So, now you see that using -b branch_name
basically just ensures the branch_name
branch is checked-out after the clone, but still clones ALL remote branches, whereas adding also --single-branch
ensures that ONLY branch_name
is cloned, fetched, pulled, and tracked. No other remote branches will be cloned to your PC whatsoever.
Personally, I prefer the -b branch_name
option alone, because I want all branches cloned to my local PC. The one exception might be on a huge, shared mono-repo which has dozens, or even hundreds or thousands of remote branches. In that case, just use -b branch_name --single-branch
to clone just the one main branch you care about and be done. Better to download 50 GiB of data for the master
branch in a huge mono-repo, for instance, than to download 200 GiB of data so you can have 2000 of your peers' branches they are working on too!
References:
- Clone only one branch
- How do you stop tracking a remote branch in Git?
git clone --branch <branchname> <remote-repo-url>
or
git clone -b <branchname> <remote-repo-url>
For cloning a specific branch you can do :
git clone --branch yourBranchName git@yourRepository.git
For cloning a branch of Git you don't have the public key to, use this:
git clone -b <branch> <Git repository URL or clone URL you get from Git repository>
精彩评论