【问题标题】:Is it good practice to store binary dependencies in source control?在源代码管理中存储二进制依赖项是一种好习惯吗?
【发布时间】:2015-06-22 19:37:18
【问题描述】:

多年来,我一直将二进制依赖项存储在 \lib 文件夹中,并将其与项目的其余部分一起检查到源代码控制中。我发现现在我们有 NuGet 和 NuGet 包还原,所以我这样做的次数减少了。

我听说有些公司强制规定不能将二进制文件签入源代码管理。引用的原因包括:

  1. 大多数 VCS 不能很好地处理二进制文件 - 差异和合并没有得到很好的支持
  2. 磁盘使用量增加
  3. 提交和更新速度较慢
  4. 存储库管理器提供的开箱即用的额外功能、控制和易用性将丢失
  5. 它鼓励进一步的不良做法;理想情况下,项目应该寻求完全自动化其构建,检查版本控制通常是手动步骤

对于绝大多数使用源代码控制的项目,是否存在支持或反对这种做法的客观论据?

【问题讨论】:

    标签: git svn version-control


    【解决方案1】:

    我强烈建议您不要使用您描述的做法(在源代码控制中禁止二进制文件的做法)。实际上,我将其称为组织反模式。

    最重要的一条规则是:

    您应该能够在新机器上签出一个项目,并且它必须开箱即用。

    如果这可以通过 NuGet 完成,那么就可以了。如果没有,请检查二进制文件。如果有任何法律/许可问题,那么您的存储库中应该至少有一个包含所有必需信息的文本文件(名为 how_to_compile.txt 或类似文件)。

    这样做的另一个非常充分的理由是避免版本控制问题 - 或者你知道吗

    • 某个库的确切版本是几年前在运行的,并且
    • 如果它真的是项目中使用的实际版本,并且
    • 可能最重要的是:您知道如何获得那个确切的版本吗?

    反对上述观点的其他一些论点:

    • 签入二进制文件极大地促进了构建自动化(并且不妨碍它)。这样,构建系统就可以毫不费力地从 VCS 获得所需的一切。如果您以其他方式进行操作,则始终涉及手动步骤。
    • 只要您在 Intranet 中工作,性能考虑就完全无关紧要,而在使用基于 Web 的存储库时,性能考虑的相关性很小(我想我们所说的不超过 30-40 Megs,这对于当今的带宽而言,这并不是什么大问题)。
    • 没有任何功能丢失。这根本不是真的。
    • 正常提交等速度较慢也是不正确的。只有在处理大型二进制文件本身时才会出现这种情况,这种情况通常只发生一次。
    • 而且,如果您签入了二进制依赖项,那么您至少有一些 控制权。如果你没有,你根本就没有。这肯定有更高的错误可能性......

    【讨论】:

    • 因为几乎所有现代编程平台都使用包系统,所以你的论点失去了意义。你是对的,“你应该能够在一台新机器上检查一个项目,并且它必须开箱即用地编译。”这是通过使用适当调整的包管理系统来实现的。不应将二进制文件存储在 SOURCE 代码存储库中。
    【解决方案2】:

    这取决于工作流程和使用的 VCS。

    通过 SVN 使用基于组件的工作流程,您可以签入组件的包含和库。通过这个库和包含为其他组件创建接口。这些仅导入库并包括使用 svn:externals 而根本不导入组件的源代码。这强制执行干净的接口和不同组件之间的严格分离:组件是一个黑盒子,只能按照接口中指定的方式使用。内部结构对其他人是不可见的。使用二进制文件可以减少编译时间,并且可以减少机器上编译所需的工具数量,因为创建组件所需的专用工具在使用时不需要存在。

    但是,使用分布式 VCS 的东西不会以这种方式工作。 DVCS 依赖于克隆整个存储库。签入存储库大小的二进制文件将迅速增长,超出了这将花费太长时间的程度。虽然拥有 100GB 的 SVN 存储库不是问题,因为结帐只处理一个小几个数量级的修订版,但拥有该大小的 Git/Mercurial/Bazaar 存储库将使其非常不可用,因为克隆需要很长时间。

    因此,签入二进制文件是否是一个好主意取决于您的工作流程,也取决于使用的工具。

    【讨论】:

      【解决方案3】:

      我自己的经验法则是,生成的资产不应受版本控制(无论它们是二进制还是文本)。有一些东西,比如图像、音频/视频文件等,可能会被签入,而且是有充分理由的。

      至于具体点。

      1. 您不能合并这些类型的文件,但它们通常只是被替换而不是分段合并。对于使用自定义差异的某些文件,可能可以对它们进行区分,但通常,这是使用某种元数据(如版本号)来完成的。

      2. 如果您有一个大文本文件,则磁盘使用率不是反对版本控制的理由。同样在这里。这个想法是需要跟踪对此文件的更改。在最坏的情况下,可以将这些资产放在单独的存储库中(不会经常更改),然后使用 git 子模块将其包含在当前存储库中。

      3. 这根本不是真的。对该特定文件的操作可能会更慢,但没关系。文本文件也是如此。

      4. 我认为在版本控制中添加内容会增加 repo 提供的便利性。经理。

      5. 这触及了我的观点,即不应生成相关文件。如果未生成文件,则签出和构建是一个步骤。没有“下载二进制资产”阶段。

      【讨论】:

        【解决方案4】:

        几乎所有现代编程平台都有自己的包管理器。这意味着,共享二进制文件最好捆绑到包中并使用包管理系统发布。在大多数情况下,即使是没有相应官方包的第三方二进制文件和资源,您也可以将其打包到您自己的包中,将其存储在您的私有包存储库中,然后在您自己的 CI/CD 系统中使用它来构建您的产品。 因此,对于 source 代码使用 source 代码存储库,对于二进制文件和第 3 方依赖项使用包管理系统。关注点分离。

        【讨论】:

          猜你喜欢
          • 2022-06-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-03
          • 2010-09-27
          • 2020-08-25
          • 2022-09-30
          相关资源
          最近更新 更多