如果两个 Git 仓库共享相同的代码,会发生什么?

77

我有一个项目,其中包括客户端和服务器端。为了清晰分离代码,我希望将客户端和服务器端的代码放在不同的Git仓库中。然而,它们共享一些文件,理想情况下,这些共享文件在客户端和服务器端始终保持相同。

那么我该如何处理呢?最好是创建第三个存储库来存放共享代码吗?

5个回答

52

我不会就“你应该如何处理这个问题”给出建议。但是我将解释如何将第三方代码库与其他代码库集成:这需要使用 git 子模块。git 子模块允许您引用指定路径处的 git 存储库的快照:

git submodule add git://example.com/repository.git path

随后创建提交。现在给定的存储库的快照被引用在 path 中。

填充子模块

  1. 执行 git submodule init
  2. 执行 git submodule update

每个已配置的子模块都将更新以匹配其应该看起来的状态。

将子模块更新到较新的提交

  1. 切换到子模块的目录中
  2. 使用 git pull / git fetch + git checkout 执行更新子模块到所需的提交/标签
  3. 创建一个新的提交以更新 .gitmodules 文件中的提交信息

请参阅官方手册以获取有关子模块的更多信息。


值得一提的是,子模块只会跟踪主分支。 - Dev Yego
2
@DevYego 我不确定你的意思。你可以让子模块指向任何提交,而不仅仅是主分支。跟踪是本地与远程分支的概念,你可以在每个子模块的 git 中管理它 -- 它并不知道自己是一个子模块。 - Amichai Schreiber

13
如果它们共享通用代码,我认为有两个明智的选择。将通用代码分离到自己的项目中,或将服务器和客户端存储库合并以使它们更容易一起工作。
是否值得花费额外的精力来分离通用代码取决于您。通用代码是独立存在还是只是特定于此产品的一堆函数?例如,如果您有一个SSL或日期解析代码共用,那么这将是一个很好的衍生项目。或者,您可能编写了特殊的配置文件解析代码,即使除了您的项目之外没有人使用它也可以单独工作。如果您仅因为两个项目共享而将通用代码拆分,那就不要麻烦了,它将没有自己的方向。将其拆分只会成为服务器和客户端团队开发的障碍。
是否应该合并客户端和服务器是另一个考虑因素。这也取决于是否将它们视为单独的产品。它们作为单独的产品有用吗?客户端和服务器的不同版本可以一起工作,还是必须是相同的版本?不同的人是否在客户端和服务器上工作?您想将所有内容都保存在一个超级存储库中的事实表明不需要。

如果您打算将项目分成多个存储库(客户端、服务器、相关项目)请参考TimWolla的答案

如果您不确定,可以将它们全部合并到一个存储库中,使用server/client/common/作为顶级目录。如果它们的关注点交织在一起,请将它们放在一起。这也将更容易发现和迁移重复的代码。您可以开始拆分它们并创建具体的“common”项目,在那时它们应该被分离成自己的存储库。


7

TL;DR

使用Git子模块来保存您的公共代码。这就是它们设计的用例。虽然还有其他选项,但大多数仅适用于在同一文件系统上的存储库,并且在克隆到网络上时几乎没有优势。

公共代码 vs. 相同文件

通常处理公共代码的正确方法是通过子模块子树合并。但是,如果您拥有(并将保持)相同的文件资产,则可以利用支持符号链接的文件系统上的符号链接。这种方法至少有三个缺点:

  1. 只有一个存储库会有“真正”的文件。另一个存储库只包含指向可能存在于不同文件系统上的文件的符号链接。
  2. Windows系统没有Linux / Unix样式的符号链接,因此可能存在互操作性问题。
  3. 除非您处理真正大的二进制文件,否则共享链接的空间节省可能很小,不值得花费这些努力。

您还可以研究使用可替代项在同一文件系统上的存储库之间共享对象。手册说(重点在我的):

您可以使用objects/info/alternates或$GIT_ALTERNATE_OBJECT_DIRECTORIES机制从其他对象存储中借用对象。具有这种不完整对象存储的存储库不适合发布以供愚蠢传输使用,但只要objects/info/alternates指向它借用的对象存储,就可以正常使用。

这种高级用法通常用于加速类似Atlassian Stash的系统上的分叉,而不是共享特定的二进制文件,但是如果您想要玩弄电锯,则可以使用这些工具。


感觉很奇怪,当两个仓库中的文件不明显时,一个仓库有“真实”的文件。你需要记住哪个仓库有真实的文件。 - Guillermo Mosse


1
使用包管理器(例如Node.js的NPM,具体取决于您的语言/环境),将常用文件移至包中,可能还要添加一个后安装脚本,并在客户端和服务器包中都安装这个共同包。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接