如何在 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>]

&lt;url&gt;是远程仓库的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 &lt;url&gt; --branch &lt;branch&gt; --single-branch &lt;folder&gt; 就像一个魅力。 是的,我认为是时候更新已接受的答案了 :) 这确实“像魅力一样工作” 另外,这在进行浅层克隆时是隐含的。这使得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 &lt;branch name&gt; 一起使用,否则只会克隆远程主 HEAD(默认为 master)

永远记得执行 Ctrl + F5 来读取新的源,而不是来自缓存的源 :-) (我不是很长时间都不知道这个选项。)

【讨论】:

git clone --branch --single-branch 【参考方案8】:

只克隆一个分支。这是最简单的方法:

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,远程分支为 masterversion_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 &amp;&amp; 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 fetchgit 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 &lt;http url&gt; 部分将所有分支克隆到您的本地计算机,而不仅仅是您想要克隆的一个分支。这是因为它会将所有分支提取到您的本地远程跟踪 remote_name/branch_name 分支,这些分支确实是这些分支的本地克隆。执行git branch -a 以查看系统上的所有本地和本地远程跟踪(获取)分支,以证明这一点。但是,使用--single-branch 选项确实可以使其他分支远离您的系统,而git branch -a 只会显示您想要的一个分支。 我没有对你投反对票,但这就是你投反对票的原因:人们认识到你的答案实际上克隆了整个回购,而不仅仅是一个分支,这表明你真的不知道这里发生了什么,所以他们对你投了反对票。

以上是关于如何在 Git 中克隆单个分支?的主要内容,如果未能解决你的问题,请参考以下文章

Git:如何在不丢失当前分支的情况下克隆项目?

git 如何克隆分支上的项目到本地

如何克隆 git 裸仓库并更改分支名称

如何在IDEA上使用Git克隆下载创建好的项目和分支提交项目

在克隆之前更改 SSH 远程上的 Git 分支

Git:如何从远程分支更新/签出单个文件?