Git 在源代码管理中存储二进制依赖项是一种好的做法吗?

Git 在源代码管理中存储二进制依赖项是一种好的做法吗?,git,svn,version-control,Git,Svn,Version Control,多年来,我一直将二进制依赖项存储在\lib文件夹中,并与项目的其余部分一起将其检查到源代码管理中。现在我们有了NuGet和NuGet包还原,我发现我做得更少了 我听说一些公司强制执行一项规则,即不能将二进制文件签入源代码管理。理由包括: 大多数VCS不能很好地处理二进制文件-不支持差分和合并 磁盘使用率增加 提交和更新速度较慢 存储库管理器提供的开箱即用的额外功能、控制和易用性将丢失 它鼓励进一步的不良做法;理想情况下,项目应该寻求完全自动化其构建,检查版本控制通常是一个手动步骤 对于绝大多数使

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

我听说一些公司强制执行一项规则,即不能将二进制文件签入源代码管理。理由包括:

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

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

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

    最重要的一条规则是:

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

    如果这可以通过NuGet实现,那么也可以。如果没有,请检入二进制文件。如果存在任何法律/许可问题,那么您的回购协议中至少应该有一个包含所有必需信息的文本文件(名为
    how_to_compile.txt
    或类似文件)

    这样做的另一个非常重要的原因是为了避免版本控制问题——或者你知道吗

    • 几年前运营的某个图书馆的确切版本是什么
    • 如果它真的是项目中使用的实际版本
    • 也许最重要的是:你知道如何得到准确的版本吗
    其他一些反对上述观点的论点:

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

    事情取决于工作流程和使用的VCS

    通过SVN使用基于组件的工作流,可以检入组件的include和libs。这样,libs和includes就为其他组件创建了接口。这些只导入libs,包括使用svn:externals,而根本不导入组件的源代码。这将强制执行干净的接口和不同组件之间的严格分离:组件是一个只能在接口中指定的情况下使用的黑盒。内部结构是别人看不见的。使用二进制文件可以减少编译时间,并可能减少机器上编译所需的工具数量,因为创建组件所需的专用工具在使用它时不需要出现

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


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

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

    至于具体的几点

  • 您无法合并这些类型的文件,但它们通常只是被替换,而不是分段合并。对于某些文件,可以使用自定义文件来区分它们,但一般来说,这是使用某种元数据(如版本号)来完成的

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

  • 这根本不是事实。对该特定文件的操作可能较慢,但这没关系。文本文件也是如此

  • 我认为版本控制增加了回购协议提供的便利。经理

  • 这涉及到我的观点,即不应该生成有问题的文件。如果未生成文件,则签出和生成是一个步骤。没有“下载二进制资产”阶段


  • 几乎所有现代编程平台都有自己的包管理器。这意味着,共享二进制文件最好捆绑到包中,并使用包管理系统发布。即使是第三方二进制文件和资源