两个 Git 个存储库共享公共代码

Two Git repositories share common code

所以我有一个包含客户端部分和服务器部分的项目。我希望客户端和服务器代码位于不同的 Git 存储库中,以便清楚地分离代码,但是,它们共享一些文件,理想情况下,共享文件在客户端和服务器中始终相同。

我该怎么办?有公共代码的第三个存储库更好吗?

我不会给出“你应该怎么做”的建议。但我将解释如何将带有公共代码的第三个存储库集成到其他存储库中:这是 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 文件中的提交

查看 official manual 了解有关子模块的更多信息。

如果他们共享通用代码,我看到两个明智的选择。将公共代码分离到其自己的项目中,或合并服务器和客户端存储库,以便更轻松地协同工作。

分离公共代码是否值得付出额外的努力取决于您。通用代码本身是否有意义,或者只是该产品特定的一堆功能?例如,如果您有一个共同的 SSL 或日期解析代码,这将成为一个很好的衍生项目。或者,也许您已经为配置文件解析编写了特殊代码,即使除了您的项目之外没有人会使用它,它也可以独立运行。如果您只是因为两个项目共享公共代码而拆分公共代码,请不要打扰,它没有自己的方向。剥离它只会成为服务器和客户端团队开发的障碍。

是否应该合并客户端和服务器是另一个考虑因素。它还归结为将它们视为单独的产品是否有意义。它们作为单独的产品有用吗?不同版本的客户端和服务器是否可以协同工作,还是必须是同一个版本?不同的人在客户端和服务器上工作吗?您想将所有内容保存在一个超级存储库中这一事实拒绝了。

如果您确实分成多个存储库(客户端、服务器、相关项目)

如果您不确定,请将它们全部合并到一个包含 server/client/common/ 顶级目录的存储库中。如果他们的顾虑纠缠在一起,就把它们放在一起。这也将使发现和迁移重复代码变得更加容易。您可能会努力解开它们并创建具体的 "common" 项目,那时它们应该被分离到它们自己的存储库中。

TL;DR

只需使用 Git 个子模块来保存您的公共代码。这就是他们的用例。存在其他选项,但主要用于同一文件系统上的存储库,并且在通过网络克隆时几乎没有优势。

通用代码与相同文件

普通代码的正确处理方式通常是通过submodules or subtree merging。但是,如果您拥有(并将保持)相同的文件资产,那么您可以在支持它们的文件系统上利用符号链接。这种方法至少存在三个缺点:

  1. 只有一个存储库会有 "real" 文件。另一个存储库将只包含指向可能存在或可能不存在于不同文件系统上的文件的符号链接。
  2. Windows 系统没有 Linux/Unix-style 符号链接,因此互操作性可能是个问题。
  3. 除非您处理的是非常大的二进制 blob,否则 space 共享链接的节省可能是最小的,不值得付出努力。

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

You could be using the objects/info/alternates or $GIT_ALTERNATE_OBJECT_DIRECTORIES mechanisms to borrow objects from other object stores. A repository with this kind of incomplete object store is not suitable to be published for use with dumb transports but otherwise is OK as long as objects/info/alternates points at the object stores it borrows from.

这种高级用法通常用于加快在 Atlassian Stash 等系统上的分叉,而不是用于共享特定的 blob,但如果您想兼顾电锯,这些工具就在那里。

使用子模块、子树或子库:

https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407

https://medium.com/@porteneuve/mastering-git-subtrees-943d29a798ec

https://github.com/ingydotnet/git-subrepo#readme

使用包管理器(例如 node.js 的 NPM,取决于您的 language/environment),
将公共文件移动到一个包中,
也许添加一个 post-安装脚本,
并在客户端和服务器包中安装通用包