【问题标题】:Two Git repositories share common code两个 Git 存储库共享公共代码
【发布时间】:2015-04-06 02:21:33
【问题描述】:

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

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

【问题讨论】:

    标签: git


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:
      【解决方案3】:

      TL;DR

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

      通用代码与相同文件

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

      1. 只有一个存储库具有“真实”文件。另一个存储库将仅包含指向可能存在或不存在于不同文件系统上的文件的符号链接。
      2. Windows 系统没有 Linux/Unix 样式的符号链接,因此互操作性可能是个问题。
      3. 除非您要处理非常大的二进制 blob,否则共享链接节省的空间可能很少,而且不值得努力。

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

      您可能正在使用 objects/info/alternates 或 $GIT_ALTERNATE_OBJECT_DIRECTORIES 机制从其他对象存储中借用对象。具有这种不完整对象存储的存储库不适合发布用于哑传输,但只要对象/信息/交替点在它借用的对象存储处,就可以了。

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

      【讨论】:

      • 在不明显的情况下,一个存储库拥有“真实”文件感觉很奇怪。您需要记住哪个 repo 具有真实文件
      【解决方案4】:

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

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

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

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

      如果您不确定,请将它们全部合并到一个包含server/、client/ 和common/ 顶级目录的存储库中。如果他们的担忧纠缠不清,就把它们放在一起。这也将更容易发现和迁移重复的代码。您可能会致力于解开它们并创建具体的“通用”项目,那时它们应该被分拆到自己的存储库中。

      【讨论】:

        【解决方案5】:

        我不会就“你应该如何去做”给出建议。但我将解释如何将第三个存储库与公共代码集成到其他存储库中:这是 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 了解有关子模块的更多信息。

        【讨论】:

        • 值得一提的是,子模块只会从主分支跟踪。
        • @DevYego 我不确定你的意思。您可以让子模块指向任何提交,而不仅仅是指向主分支。跟踪是本地与远程分支的概念,您可以在每个子模块的 git 中进行管理——它不知道它是一个子模块。
        猜你喜欢
        • 2014-05-30
        • 1970-01-01
        • 2011-12-27
        • 1970-01-01
        • 1970-01-01
        • 2016-05-23
        • 2016-08-03
        • 2019-02-10
        • 2012-01-23
        相关资源
        最近更新 更多