我一直想要实现这样的功能——将工作或内部驱动器存储库B和USB备份驱动器存储库C与相同的远程存储库A同步,而不必为每个存储库单独从A重新获取。在开始撰写自己的问题之后,出现了与此问题相关的链接以及这个问题:
如何将本地git存储库中的所有远程分支转换为本地跟踪分支
对于发现第二种解决方法更可取的人可能会有用;像你一样,我也不喜欢那种方法,它很混乱。
阅读您的第一个解决方法让我思考并阅读了git手册 -
git clone --mirror
非常接近我们/我想要的内容,因为正如手册所说:
设置源存储库的镜像。这意味着--bare。与--bare相比,--mirror不仅将源的本地分支映射到目标的本地分支,还映射所有引用(包括远程跟踪分支、注释等),并设置一个refspec配置,使得在目标存储库中使用git remote update更新所有这些引用。
所以git clone --mirror
会在本地克隆中设置所有所需的分支等,以便有效地创建其他本地克隆/仓库(例如B和C)。非裸露存储库中“镜像”的问题在于它很混乱;因此,我们似乎确实想要至少一个“主要镜像”裸仓库“D”,但使用git clone --mirror
(而不是--bare
)。
拼图的最后一块是使我们的“工作克隆”B尽可能共享此“主”仓库D的objects/
存储库,因为它们位于同一文件系统“挂载空间”中(如果有的话),这意味着您不能跨越挂载点使其正常工作。
从头开始创建D(请参见下面的链接以将现有存储库转换为D):
git clone --mirror git://blah.com/A.git D.git
从D创建B:
git clone ../D.git/ B.git
并且Git会自动处理正确的事情-如果D和B没有越过挂载障碍,则意味着git clone --local
。
很不幸,据我所知,更新“本地工作克隆”B仍然需要两个步骤 - 在D中执行
git fetch --all
,然后在B中执行
git fetch --all
或
git pull
。当然,如果适合您选择的工作流程,您可以编写一个git-fetch包装脚本来完成两个步骤。
在我的情况下,C也是一个
--mirror
存储库(至少从现在开始大约5分钟后它将是这样 - 它只是远程存储库的备份,换句话说,它是第二个“主要镜像”)。
可以配置Repo C以从B(而不仅仅是D)复制对象。首先创建C,然后添加适当的远程,例如:
从D创建C,作为镜像:
git clone --mirror blah://my.work.pc/my/mirrors/D.git C.git
或正常克隆:
git clone blah://my.work.pc/my/mirrors/D.git C.git
然后执行:
git remote add B blah://my.work.pc/my/work/B.git
或在您已经拥有C的特定情况下,将D添加为新的远程。
然后在 C 上运行 git fetch --all
,可以从 B 和 D 抓取所有更新。
您可能需要一些 如何将现有的非裸库变成裸库? 的技巧,以及...
另一种从 B 创建 D 的方法是使用以下命令:
git clone --bare B.git D.git
结合 如何将用 --bare 克隆的 git 存储库更改为与用 --mirror 克隆的存储库匹配的存储库? 中的一些技巧-同时适当地更新 D 和 B 的远程。
请注意,由
git clone --local
创建的硬链接会被
git gc
打破,后者会定期自动运行。您可以选择
git clone -s ...
,它使用符号git链接,因此知道如何跨越本地文件系统“挂载障碍”,或者使用
git-new-workdir
命令(在git repo的contrib / dir中 - 这仅适用于非裸体repo),这两个都在这里提到:
git作为替代unison。另请参见
Git中的单个工作分支和新的
Git 2.5(Q2 2015)git checkout --to=path
选项,以获取有关
git-new-workdir
及其终极git官方替代品的一些好讨论。
为避免在使用
git clone -s
时出现意外,请确保阅读其工作方式,例如在
man git-clone
中,并且您可能希望按以下方式配置D(并阅读
man git-prune
):
git config gc.pruneExpire never
关于这两种方法的比较,请参见Brandon Casey在
git-new-workdir上的讨论中的评论,即:
“If you want to have _multiple_different_ branches checked out from the
same repository, and do development in all of them, then git-new-workdir is the right choice.”
“If you want to have the _same_branch_ checked out in multiple work directories, then cloning with -s is what you want. In this case I assume development will be performed in the original repo, and the clones will do a pull to update.”
这表明
clone -s
可能仅适用于“测试”工作目录,而不适用于开发工作目录。
如果有两个“本地主”存储库,例如D和C,每个存储库都配置为另一个存储库和存储库A的远程,则可以编辑git配置文件并剪切粘贴本地存储库条目(例如D或C)以将其移动到远程(存储库A)条目上方 - 这样git fetch --all
就会正确获取新的更改和分支,首先在本地获取(在可能的情况下),而无需手动首先获取本地存储库,然后再获取存储库A。这是我所有克隆的公共存储库的设置,它非常有效!
祝好运。