【问题标题】:Git doesn't clone all branches on subsequent clones?Git 不会在后续克隆上克隆所有分支?
【发布时间】:2011-07-30 14:51:28
【问题描述】:

我在使用克隆存储库和分支的 Git 方面遇到了一些问题,我无法找到答案。让我描述一下:我们在这里有一个裸露的主 Git 存储库,我们都从中提取和推送到,位于本地 linux 机器上,并且可以通过 ssh 访问。我将这个克隆到我的 USB 拇指驱动器,如下所示:

git clone ssh://adahl@gollum//net/repos/netcube/patches.git

这当然给了我一个本地克隆,我的拇指驱动器上有一个工作副本。我 cd 到这个,然后在这个克隆中看到一些分支:

cd patches
git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/stable

到目前为止一切顺利,但是如果我再次将拇指驱动器上的存储库克隆到我的笔记本上,那么稳定的分支就会丢失。见:

cd ..
git clone patches patches2

cd patches2

git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

我在克隆时尝试了几个选项,或者在克隆后尝试了git fetch,但没有任何东西可以将稳定分支带到 patches2 存储库。我假设我在这里缺乏对 git 的理解,只是以错误的方式使用它。有人可以指出我在使用和/或理解方面的错误吗?

【问题讨论】:

  • 感谢 cmets,我知道我的误解是什么。我想要的是用 all 来自主存储库的内容“传输存储库”,但 Git 会根据您的跟踪分支进行某种选择性克隆。使用git clone --mirror,我得到了一个中间存储库,我可以按照我的预期使用。
  • 更简单地说,git clone(没有特殊选项)不会从源仓库复制远程跟踪分支,只会复制源上的本地分支(.git/refs/heads/ 下的分支)来源,而不是.git/refs/remotes/<remote>/ 下的来源。

标签: git branch clone


【解决方案1】:

见How to clone all remote branches in Git?

如果您确实希望将远程分支包含在克隆中,则需要基于远程分支创建本地分支。但是,由于您无论如何都不会在远程分支中工作,因此您将在开始在分支上工作时立即创建本地分支。在此之前,您的克隆中并不需要它,因为您可以随时从远程获取它。

但是,如果笔记本没有网络连接,则必须为所需的所有远程分支创建本地分支,以便在克隆本地存储库时克隆它们。

如果您确实有网络连接,请使用git remote add origin2 ssh://adahl@gollum//net/repos/netcube/patches.git,然后使用git fetch origin2 - 随意将origin2 替换为更有意义的名称。

【讨论】:

  • 如果我有从笔记本到主存储库的网络连接,我无论如何都不需要传输存储库(补丁)。让我感到困惑的是,转移存储库的第一个克隆似乎是具有主存储库的 all 变更集的“精确”克隆,但第二个克隆删除了一些变更集,只是因为没有“本地分支” « 上面的标签。
  • 不,第一个克隆只是将源添加为远程(origin),从而获取其分支。但是,遥控器不会克隆,因此您的存储棒上的 repo 不会有这个遥控器或其分支。
  • 这就是我现在所做的:在我的传输存储库中创建跟踪分支,以便在后续克隆中也可以克隆这些分支。这需要更多的手动工作,但这似乎是正确的解决方案。
【解决方案2】:

"origin" 是您克隆 repo 的位置的默认名称,它会自动添加为远程(注意:远程仅表示“repo 不是当前的” - 远程可以在同一台机器上) .

在patches 中,“origin”指的是 gollum 上的原始 repo。

在patches2 中,“原点”指的是patches。

远程跟踪引用(以remotes/ 开头的引用)实际上并不是本地分支——它们只是指向最后一次知道分支在远程位置的指针。因此,在patches 中,您有原始repo 的远程跟踪引用,但在patches2,您只有patches 中本地master 分支的远程跟踪引用,因为那是patches2 的位置原点指向。

您可以在克隆后使用git remote add 将原始存储库添加为patches2 中的另一个远程,或者您可以从原始存储库而不是patches 再次克隆。

【讨论】:

  • 我无法从原始仓库克隆到 patches2,因为我无法连接到原始仓库。存储库 patches 只是一个“转移存储库”,无论如何我都不会在其中工作。
  • @LeSpocky:我认为您缺少的一点是patches2 中列为“远程”的分支都是patches 中的“本地”分支(因为这就是@ 987654335@ 指的是,就像@Amber 说的那样)。如果您还没有(本地)签出patches 中的stable 分支,那么它不会出现在patches2 的远程列表中。
  • 问题是:如果我使用 TortoiseGit 显示 all patches2 中 all 分支的变更集,似乎patches 中属于 stable 分支的变更集不会克隆到 patches2,所以即使我知道我需要哪些变更集,我也不会将它们放入第二个 repo (patches2),因为它们不是从第一个 repo (patches) 克隆的。但是,我假设带有 all 变更集的整个存储库都被克隆了,而不仅仅是其中的一部分。
  • 当你克隆一个 repo 时,你只会得到你 repo 克隆的分支中的变更集。不克隆远程跟踪参考。因此,您不会在远程跟踪参考中获得变更集。
  • 所以这是我的基本误解(我认为这是因为 mercurial 处理这个不同)。 Git 会进行某种选择性克隆,而不是总是克隆整个存储库。
【解决方案3】:

除了@ThiefMaster:

我喜欢

git clone --mirror

或

git push --mirror 

更新所有(本地和远程)分支引用和标签

其他信息 如前所述,--mirror 将真正按原样复制 repo,从而覆盖目标中的更改。源中不存在的分支将被无条件修剪。

本质上,这就像使用远程操作并执行“git remote update --prune”,不同之处在于受影响的分支可以是本地分支以及“远程”引用[1]

@LeSpocky(还有其他人?)

现在,如果更改消失,它们将永远不会产生合并问题,所以这很容易。

--mirror 以现实生活中的概念命名,因此它旨在掩盖目标中的任何差异。如果目标是非裸的,并且您提交了本地更改,您始终可以通过目标本地分支的 reflog (git log -g、git reflog) 将它们取回。

作为一般安全措施,您可以have a hook to 'git stash save' in the target。

但请记住,--mirror 旨在mirror 而这个问题实际上是关于如何将所有分支复制到裸远程。 :)

[1](参考文献在那里,但远程定义不会被复制;如果需要,请在推送目标上从 .git/config 手动复制到 .git/config)

【讨论】:

  • 如果我使用--mirror 选项来创建我的传输存储库patches,那么随后对patches2 的克隆具有稳定分支。似乎这是我想要实现的目标所需的选项。
  • 请注意,--mirror 可能会产生副作用,如果其他人在您从它克隆然后推送到它之间更改您正在镜像的存储库 - --mirror 设置推送,以便它们始终覆盖遥控器,无论是否有任何更新。
  • @Amber:更新答案以获取更多信息
  • @Amber 我是否理解正确,将更改从我的克隆推送到镜像存储库,然后从镜像存储库到主存储库会使主存储库中的新更改以某种方式消失,我可能会遇到合并问题他们?
  • @LeSpocky:在帖子中添加了答案
【解决方案4】:
$ git remote update
$ git pull --all

【讨论】:

    猜你喜欢
    • 2021-06-26
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多