如何在 Git 中克隆单个分支?
Posted
技术标签:
【中文标题】如何在 Git 中克隆单个分支?【英文标题】:How do I clone a single branch in Git? 【发布时间】:2010-12-19 04:24:17 【问题描述】:我有一个名为“skeleton”的本地 Git 存储库,用于存储项目骨架。它有几个分支,用于不同类型的项目:
casey@agave [~/Projects/skeleton] git branch
* master
rails
c
c++
如果我想签出一个新项目的主分支,我可以这样做
casey@agave [~/Projects] git clone skeleton new
Initialized empty Git repository in /Users/casey/Projects/new/.git/
一切都是我想要的。具体来说,新的 master 分支指向骨架 master 分支,我可以通过推拉来移动对基本项目设置的更改。
但是,如果我想克隆另一个分支,则不起作用。我无法得到它,所以我只拉出我想要的分支,例如rails
分支,然后新存储库有一个master
分支,它通过默认。
有什么好的方法可以做到这一点吗?或者,也许这不是 Git 想要我组织事物的方式,我当然对此持开放态度。也许我应该有多个存储库,Ruby on Rails 骨架存储库跟踪主骨架存储库?以及任何克隆 Ruby on Rails 骨架存储库的单个项目。
【问题讨论】:
git branch -a
显示什么?
git checkout -b newbranch origin/branchiwant
会更好吗? (没有--track
选项)
我认为您正在尝试做的事情是个坏主意。为不同的项目使用不同的存储库。分支是完全不同的东西。
@Manni,我是这么想的,因为 git 似乎不喜欢我在做什么。你能解释一下为什么吗?是因为树枝不应该长命吗?
@rodarmor 我认为您正在尝试做的事情是个好主意,而我正是这个问题。
【参考方案1】:
注意:git1.7.10(2012 年 4 月) 实际上允许您只克隆一个分支:
# clone only the remote primary HEAD (default: origin/master)
git clone <url> --single-branch
# as in:
git clone <url> --branch <branch> --single-branch [<folder>]
(<url>
是远程仓库的URL,不引用自己克隆的分支)
你可以在t5500-fetch-pack.sh
看到它:
test_expect_success 'single branch clone' '
git clone --single-branch "file://$(pwd)/." singlebranch
'
Tobucomments那个:
这在进行浅层克隆时是隐含的。 这使得
git clone --depth 1
成为节省带宽的最简单方法。
从 Git 1.9.0(2014 年 2 月)开始,浅层克隆支持数据传输(推/拉),因此该选项现在更加有用。
在“Is git clone --depth 1
(shallow clone) more useful than it makes out?”查看更多信息。
“撤消”浅层克隆在“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
作为Chriscmets:
让丢失的分支反转
--single-branch
的神奇路线是(git v2.1.4):
git config remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
git fetch --unshallow
在 Git 2.26(2020 年第一季度)中,“git clone --recurse-submodules --single-branch
”现在在克隆子模块时使用相同的单分支选项。
参见Emily Shaffer (nasamuffin
) 的commit 132f600、commit 4731957(2020 年 2 月 21 日)。(由 Junio C Hamano -- gitster
-- 合并到 commit b22db26,2020 年 3 月 5 日)
clone
:在 --recurse-submodules 期间通过 --single-branch签字人:Emily Shaffer签字人:Jeff King
以前,执行“
git clone --recurse-submodules --single-branch
”会导致子模块克隆所有分支,即使超级项目只克隆了一个分支。通过子模块帮助框架将
--single-branch
管道化,以便稍后将其转换为“clone
”。
【讨论】:
git clone <url> --branch <branch> --single-branch <folder>
就像一个魅力。
是的,我认为是时候更新已接受的答案了 :) 这确实“像魅力一样工作”
另外,这在进行浅层克隆时是隐含的。这使得clone --depth 1
成为节省带宽的最简单方法。
@Tobu 和 VonC --depth 1
对用户来说是不安全的,因为他们可能希望实际推/拉新克隆。
只是为了完整地说明 Peter Cordes 的更正,让丢失的分支反转 --single-branch
的魔法线是 git config remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
和 git fetch --unshallow
(git v2.1.4)【参考方案2】:
一种方法是执行以下操作。
git clone user@git-server:project_name.git -b branch_name /your/folder
branch_name
是您选择的分支,“/your/folder”是该分支的目标文件夹。确实,这会带来其他分支,让您有机会来回合并。
更新
现在,从 Git 1.7.10 开始,您现在可以这样做了
git clone user@git-server:project_name.git -b branch_name --single-branch /your/folder
【讨论】:
这可行,但它会获取 所有 分支。请参阅下面的@frerich=raabe 的回答。 谢谢。仅在我的情况下添加“-b branch_name”。它为我节省了很多时间。 是的,它工作得很好......!我更像是一个 TFS 人,我的个人项目一直在使用 git。 W.r.to git branching,我之前做错了,很高兴知道这个简单的方法,它看起来很完美!再次感谢!已经 +1 了,如果可能的话我会给 +100 :) 您还可以添加--single-branch
以仅获取与此分支关联的历史记录,而不是存储库包含的所有历史记录和标签。
@AlexNolasco 您能否编辑答案,说明什么是 /some/folder ?谢谢【参考方案3】:
使用 Git 版本 1.7.3.1(在 Windows 上),这就是我所做的($BRANCH
是我要签出的分支的名称,$REMOTE_REPO
是我要从中克隆的远程存储库的 URL):
mkdir $BRANCH
cd $BRANCH
git init
git remote add -t $BRANCH -f origin $REMOTE_REPO
git checkout $BRANCH
这种方法的优点是后续的git pull
(或git fetch
)调用也只会下载请求的分支。
【讨论】:
你的脚本和这一行有什么不同?git clone -b $BRANCH $REMOTE_REPO $BRANCH
afik 他们是一样的吗?
@Ian:一个区别是git clone -b
为您提供所有远程引用(所有远程分支和标签),如git branch -a
所示。使用我的脚本,你只会得到一个参考。
当我尝试上述方法时(比如使用 $BRANCH="nick"),我得到“致命:找不到远程 ref refs/heads/nick”。似乎对我不起作用...
请注意,即使没有-f
,-t $BRANCH
也可以工作,它会立即获取。然后,git fetch origin
将获取,git checkout $BRANCH
将建立本地分支并结帐。当您需要在获取之前配置遥控器时,这很有用,例如git config remote.origin.uploadpack=/bin/upload-pack
.
由于我使用的是“旧”公司 git (1.6.0.2),因此我必须使用上述解决方案。我和@Nick 有同样的问题。执行 git branch -a
显示 origin/$BRANCH
。做git checkout origin/$BRANCH
解决了这个问题。【参考方案4】:
你可以试试长篇大论:
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
这是做什么的:
创建并初始化一个空的 Git 存储库。 将原始存储库添加为名为 origin 的远程存储库。 仅从名为 origin 的远程获取您需要的分支。 创建并签出一个新分支,该分支设置为跟踪您刚刚克隆的源分支。希望这会是你所追求的。
【讨论】:
交换了 git remote add 的参数,但我无法让结帐工作。 “git checkout origin/rails”给了我“错误:pathspec 'origin/rails' 与 git 已知的任何文件都不匹配。”替代方案给了我“致命的:git checkout:更新路径与切换分支不兼容。” @rodarmor:已经更正了 git 远程命令,谢谢。你能粘贴git branch -r
的输出吗?
@jkp,实际上git branch -r
没有输出。
@rodarmor:我已经更正了这个例子,这绝对有效(经过测试)。 HTH(你可以接受它,一旦测试过你喜欢的;))
-b 开关相对较新。上次我在 debian 上运行它时它不可用,IIRC【参考方案5】:
git clone <url> --branch <branch> --single-branch
只需输入 URL 和分支名称。
【讨论】:
【参考方案6】:您可以使用以下命令来完成:
git clone -b branch_name --single-branch project_url local_folder_to_clone_in
【讨论】:
工作得很好,实际上我在源树中克隆单个分支时遇到了问题,因此手动完成了【参考方案7】:来自git-clone man page:
--single-branch
是你克隆时的朋友
请记住与--branch <branch name>
一起使用,否则只会克隆远程主 HEAD(默认为 master)
永远记得执行 Ctrl + F5 来读取新的源,而不是来自缓存的源 :-) (我不是很长时间都不知道这个选项。)
【讨论】:
git clone只克隆一个分支。这是最简单的方法:
git clone -b BRANCH_NAME --single-branch git@bitbucket.org:___/PROJECTNAME.git
【讨论】:
【参考方案9】:这里有很多答案提到:
下载 1 分支(with --single-branch
部分):
# (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
...或某个版本,还有一些只提到:
下载所有分支(不包括--single-branch
部分):
# (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
但是,我想稍微解释一下这两件事,并展示一组更熟悉的等效命令,这样我们就可以看到每个幕后发生的事情.
假设您在 GitHub 上有一个远程仓库 https://github.com/micronucleus/micronucleus.git,远程分支为 master
和 version_2.5
(这是一个您现在可以实际运行的真实示例)。
上面第二条命令的分解:
第二条命令 (git clone -b version_2.5 https://github.com/micronucleus/micronucleus.git
) 将所有远程分支克隆到您的本地 PC,然后检出 version_2.5
分支而不是 master
分支。该命令相当于执行此操作:
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
-b version_2.5
部分自动为我们签出version_2.5
分支,而不是master
。
git branch -a
向我们展示了所有分支都被克隆到了我们的本地 PC。在这里您可以看到我们所在的本地分支version_2.5
,以及本地存储的远程跟踪分支 origin/HEAD
(指向origin/master
),以及origin/master
,以及origin/version_2.5
:
$ git branch -a
* version_2.5
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/version_2.5
我们还可以查看我们的fetch
引用是什么。您可以打开.git/config
文件直接查看它们,或者直接运行git config remote.origin.fetch
:
$ git config remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
您可以在上面看到我们的git fetch
命令(也由git pull
触发,因为它等同于git fetch && git merge
)被配置为获取origin
远程中所有分支的所有头。我不是这方面的专家,但我相信这就是+refs/heads/*:refs/remotes/origin/*
的意思。
上面第一个命令的分解:
第一个命令 (git clone -b version_2.5 --single-branch https://github.com/micronucleus/micronucleus.git
) 只将version_2.5
分支克隆到您的本地PC,它还会检查它。该命令相当于执行此操作(至少在最终结果中,除了它在开始时下载的数据也少得多,因为它只克隆一个分支而不是所有分支):
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"
-b version_2.5
部分导致version_2.5
分支默认签出而不是master
分支(如上所述),--single-branch
部分导致:
-
没有其他分支要克隆到我们的 PC 上,并且
git fetch
被配置为 当我们调用 git fetch
或 git pull
! 时不会获取其他分支
这个命令是真正克隆的,并且只会获取我们想要的一个分支,就是这样!
git branch -a
向我们展示了只有 version_2.5
分支被克隆和签出。这里我们通过*
看到哪个分支被签出,我们还看到我们有一个用于origin/version_2.5
的本地存储远程跟踪分支:
$ git branch -a
* version_2.5
remotes/origin/version_2.5
我们还可以查看我们的fetch
引用是什么。您可以打开.git/config
文件直接查看它们,或者直接运行git config remote.origin.fetch
:
$ git config remote.origin.fetch
+refs/heads/version_2.5:refs/remotes/origin/version_2.5
您可以在上面看到我们的git fetch
命令只会从origin/version_2.5
远程分支获取version_2.5
分支头。而已!请注意,不会获取任何其他远程分支。
总结:
所以,现在您看到使用-b branch_name
基本上只是确保在克隆后签出branch_name
分支,但仍会克隆所有远程分支,同时添加--single-branch
确保仅克隆branch_name
、提取、拉取和跟踪。 任何其他远程分支都不会克隆到您的 PC。
就个人而言,我更喜欢单独使用-b branch_name
选项,因为我希望将所有 分支克隆到我的本地PC。一个例外可能是一个巨大的、共享的单一仓库,它有几十个,甚至成百上千个远程分支。在这种情况下,只需使用-b branch_name --single-branch
克隆您关心的一个主分支并完成。例如,最好在一个巨大的单一存储库中为master
分支下载 50 GiB 的数据,而不是下载 200 GiB 的数据,这样您就可以拥有他们正在处理的 2000 个同行的分支!
参考资料:
-
Clone only one branch
How do you stop tracking a remote branch in Git?
【讨论】:
【参考方案10】:要克隆一个特定的分支,你可以这样做:
git clone --branch yourBranchName git@yourRepository.git
【讨论】:
git@yourRepository.git 是什么意思?【参考方案11】:要克隆没有公钥的 Git 分支,请使用:
git clone -b <branch> <Git repository URL or clone URL you get from Git repository>
【讨论】:
【参考方案12】:有点晚了,但我想添加我用来解决这个问题的解决方案。我找到了解决方案here。
无论如何,问题似乎是在问“如何从另一个 repo 的分支开始一个新项目?”
对此,我使用的解决方案是首先在 github 或其他任何地方创建一个新的 repo。这将作为新项目的回购。
在您的本地计算机上,导航到包含您要用作新项目模板的分支的项目。
运行命令:
git push https://github.com/accountname/new-repo.git +old_branch:master
这会将 old_branch 推送到 new-repo 并使其成为新 repo 的 master 分支。
然后,您只需将新的 repo 克隆到新项目的本地目录,并且您在旧分支上启动了一个新项目。
【讨论】:
【参考方案13】:让我们以烧瓶回购为例。除了master之外,它还有3个分支。让我们检查一下 1.1.x 远程分支
克隆 git 仓库
git clone https://github.com/pallets/flask
cd 进入 repo。
cd flask
获取远程分支 1.1.x
git fetch origin 1.1.x
签出分行
git checkout 1.1.x
您将切换到 1.1.x 分支,它将跟踪远程 1.1.x 分支。
【讨论】:
【参考方案14】:打开 cmd。
cd folder_name # enter the path where to clone the branch
只有一个命令:
git clone url_of_projecturltoclone -b branch_name
【讨论】:
【参考方案15】:主要有两种解决方案:
您需要使用 -b 命令开关指定分支名称。这是克隆特定 git 分支的命令语法。
git clone -b <BRANCH_NAME> <GIT_REMOTE_URL>
示例:
git clone -b tahir https://github.com/Repository/Project.git
以下命令将从 git 存储库中克隆分支 tahir。上述命令仅克隆特定分支,但会获取其他分支的详细信息。您可以使用命令查看所有分支的详细信息。
git branch -a
您可以使用--single-branch
标志来防止获取其他分支的详细信息,如下所示:
git clone -b <BRANCH_NAME> --single-branch <GIT_REMOTE_URL>
示例:
git clone -b tahir --single-branch \
https://github.com/Repository/Project.git
现在,如果您执行git branch -a
,它只会显示您已克隆的当前单个分支,而不是所有分支。所以这取决于你想要它。
【讨论】:
这不太对。获取是克隆!当您获取远程分支时,您正在将该远程分支的内容克隆到该远程分支的 本地存储remote_name/branch_name
(例如:origin/branch1
)本地远程跟踪克隆。所以,当你说:“上面的命令 [引用git clone -b tahir https://github.com/Repository/Project.git
] 只克隆特定分支但获取其他分支的详细信息。”,这是错误的。实际上,它克隆了所有分支。它只是签出克隆所有分支后的tahir
分支。
这意味着对于您的项目符号 2,您还应该将其更改为(“您可以使用 --single-branch
标志来防止获取其他分支的详细信息,如下所示:”)改为:“您可以使用--single-branch
选项可防止克隆(获取)所有其他分支。相反,它只会克隆(获取)然后签出您指定的一个分支。请参见下面的示例:..."。【参考方案16】:
如果你想要一个浅克隆,你可以这样做:
git clone -b mybranch --depth=1 https://example.com/myproject.git localname
--depth=1
暗示--single-branch
。
【讨论】:
【参考方案17】:如果你想保持分支独立,你可以使用这个命令来 git 单个分支并重命名文件夹
git clone -b [branch-name] --single-branch [url] [folder_name]
例子
git clone -b mybranch --single-branch git://github/repository.git project_mybranch
【讨论】:
【参考方案18】:这应该可以工作
git clone --single-branch <branchname> <remote-repo-url>
git clone --branch <branchname> <remote-repo-url>
【讨论】:
【参考方案19】:?️一些性能测量?️
我比较了两种建议的方法,发现一种比另一种更快(并且更小)(如果您的唯一目标是克隆,而您不太关心其他内容,这是有利的)。
我发现最重要的性能指标是--depth
,也就是说VonC的answer是最快的。
自己试试吧:
time bash -cl "git clone --single-branch --depth=1 --branch=$MYBRANCH $MYGITURL"
我用一个历史悠久、分支众多的大项目对此进行了测试,这种方法大约需要 6s。
请注意,与此线程中几个 cmets 所声称的相反,(至少在最近的 git 版本中),这只会checkout
目标分支。 git branch -a
仅列出该单个分支。
亚军
相比之下,frerich-rabe 的 approach 始终需要 26 秒:
time bash -cl "git init && git remote add -t $MYBRANCH -f origin $MYGITURL && git checkout $MYBRANCH"
比较两者时,还需要注意的是,在我的例子中,目标分支是其父分支的精简版。第一种方法的下载进度条反映了大小的减小( 90MB)。 (我敢肯定,有更成熟的方法来衡量总下载量,但我还没有研究过。)
【讨论】:
【参考方案20】:git clone --branch branch-name repo-URI
示例:
git clone --branch dev https://github.com/ann/cleaningmachine.git
dev: 这是branch-name
https://github.com/ann/cleaningmachine.git:这是repo-URI
【讨论】:
【参考方案21】:类似于@nosaiba-darwish 在这里所说的:here
这是我们公司通常做的事情:
git clone -b <name_of_branch> --single-branch <git_url> folder_to_clone_locally
【讨论】:
【参考方案22】:对于像我这样的新手, 只需运行下面的代码
git clone https://gitlab.com/repo/repo.git --branch <name of branch> --single-branch
【讨论】:
【参考方案23】:我是这样做的
git clone -b
示例:
git clone -b master https://gitlab.com/jhondoe/applicationproject.git
或
git clone -b master git@gitlab.com:jhondoe/applicationproject.git
【讨论】:
【参考方案24】:git clone --single-branch -b [branch name] [repository URL]
【讨论】:
【参考方案25】:分两步完成
克隆存储库
git clone <http url>
签出你想要的分支
git checkout $BranchName
【讨论】:
实际上,git clone <http url>
部分将所有分支克隆到您的本地计算机,而不仅仅是您想要克隆的一个分支。这是因为它会将所有分支提取到您的本地远程跟踪 remote_name/branch_name
分支,这些分支确实是这些分支的本地克隆。执行git branch -a
以查看系统上的所有本地和本地远程跟踪(获取)分支,以证明这一点。但是,使用--single-branch
选项确实可以使其他分支远离您的系统,而git branch -a
只会显示您想要的一个分支。
我没有对你投反对票,但这就是你投反对票的原因:人们认识到你的答案实际上克隆了整个回购,而不仅仅是一个分支,这表明你真的不知道这里发生了什么,所以他们对你投了反对票。以上是关于如何在 Git 中克隆单个分支?的主要内容,如果未能解决你的问题,请参考以下文章