我们想共享运行时项目二进制文件。所以每个团队成员都可以使用当前的工作版本。在 SVN 中存储运行时二进制文件是否可以接受/很好?
15 回答
您可能希望将二进制文件存储在版本控制系统中的两个常见原因是(写于 2009 年):
- 存储外部第三方库。
通常将它们存储到 Maven 存储库中,但是将它们存储到 SVN 允许您拥有一个且只有一个引用来满足您的所有需求:获取源代码,并获取编译这些源代码所需的库。全部来自一个存储库。
(正如ivorujavaboy在 2017 年指出的那样:“目前这样做的唯一充分理由是,如果您拥有永远不会改变的 STATIC 库,这是非常罕见的情况”)
- 存储交付以加快部署。
通常交付(您构建以部署到生产中的可执行文件)是按需构建的。
但是,如果您有很多预生产环境,并且如果您有很多交付,那么为组装、集成、认证、预生产平台构建它们的成本可能会很高。
一种解决方案是构建一次,将它们存储在 SVN 的交付部分,然后直接在不同的环境中使用它们。
注意:
这也适用于开发元素:如果您有一个生成 900 个 POJO 文件(通过 XML 绑定)的Jaxb进程,并且您需要在多个环境中下载该开发集,您可能需要 1 个压缩文件复制事务,而不是 900 个那些。
所以是的,出于正确的原因,“在 SVN 中存储运行时二进制文件是可以接受的/很好的”。
话虽如此:
- Wim Coenen正确地提到了缺点(不好的做法、速度慢、来源和存储交付之间的不匹配)
- Vladimir提倡使用交付参考(Nexus 或 Vladimir 提到的Apache ivy)
- RogerV说明了使用所述交付参考的优势(在他的案例中为 Nexus)
不,不要将二进制文件存储在其源代码旁边(除非您有充分的理由来抵消这些缺点)。
缺点:
- 它鼓励大型项目中的不良构建实践。最佳实践是完全自动化您的构建。提交二进制文件使您可以忽略这一点:“只需手动为已更改的部分进行构建”:-(
- 较慢的更新和提交
- 更改源代码但未更改相应二进制文件的提交会引起开发人员的混淆。您如何检测到不匹配?
svn update
将更新您的二进制文件的时间戳,混淆您的构建工具,从而错误地认为二进制文件比您的源代码更改更新。- 导致二进制文件的虚假冲突
svn update
和svn merge
- 它在存储库中使用更多磁盘空间。(根据您的项目,这可能可以忽略不计。)
通常,避免提交从其他版本化资源以确定性方式自动生成的任何内容。没有冗余 -> 没有出现不一致的机会。
相反,使用持续集成服务器在每次提交时自动重建(并运行测试)。如有必要,让此构建服务器在某处(SVN 之外)发布二进制文件。
现在,这并不意味着您应该将此作为绝对规则或避免使用所有二进制文件。无论如何,将您的构建工具和第三方闭源二进制文件放入您的项目中。并在有意义的时候做出例外。理想情况下,新开发人员应该能够进行检查并立即启动构建脚本,而无需花费一两天时间来设置他的环境。
我想说,如果它让你的团队的生活更轻松,那就去做吧。如果它减少了设置工作开发环境所需的时间,那就去吧。
正如许多人已经说过的,这是可以接受的。
是的,从一个位置将所有东西都放在手边很方便,您可以(例如)从那里签出已经以二进制形式存在的旧标签及其正确的依赖关系。
但这并不好,尤其是出于备份目的。我们将所有二进制文件(和部分依赖项)存储在 SVN 中,并且随着项目的增长,二进制部分也是如此。
不幸的是,svnadmin dump
只是转储所有内容,您无法指定要排除的存储库路径。因此,备份(和升级 svn 服务器)变得非常痛苦!
如果您在我们的案例中经过不长的时间添加这些二进制文件不再有用,我敢肯定我不会在类似的情况下再次这样做(但我会为较小的项目做)。
所以我建议在做这件事之前三思而后行,并尝试预测你能成长多大以及可能发生的其他事情。
不是为了这个目的,不。您应该使用外部文件存储,例如 FTP 或 Web 服务器。这样就可以轻松下载特定版本的运行时二进制文件,而无需先在 SVN 中更新到该版本。
每当我在 Subversion 目录中看到一个库时,我都会问以下问题:
- 它是什么版本?(通常你有
axis.jar
和没有axis-1.4.jar
) - 为什么包括在内?(尤其是依赖项的依赖关系)
如果您没有适当的依赖管理系统,您通常无法回答这两个问题。这是通往 Jar Hell 的第一步。
我可以推荐带有 Intranet 存储库的Apache Ivy (其他人可能对 Maven 发誓)。使用 Ivy,我不必将库存储到 SVN 中,并且总能回答上述问题。
是的,存储它。
我们曾经将交付给客户的二进制文件存储在 SVN 存储库中以跟踪它。
将二进制文件存储在 SVN(或源代码控制)中的另一种用途是,如果您向公司中不想构建项目以节省构建时间的其他团队提供一些内部实用程序模块。我相信这是一种普遍的做法。
但是我们从不允许存储 Eclipse 的 .classpath 和 .project 文件(工作空间相关设置)。
我们的 Java .jar 文件构建绑定在它们的 .jar 文件依赖项中,我们正在检查到 svn。很多这在实践中是多余的,但我们希望确保我们生成的每个 Java 应用程序构建都精确地具有它接受 QA 的库。
然而,真正让我感到恼火的是,当我开始远程连接到存储库并进行同步时。只需翻阅所有二进制库就需要很长时间。
我们已经放弃了这种做法,现在使用 Maven 来管理库依赖项——即使对于我们仍在使用 ant 构建的项目也是如此。没有更多的二进制文件被检入 svn。由于这种战略转变,生活在多个方面都好得多。我们可以严格控制我们想要的库依赖版本。
对于我们的 .NET 构建,我的一位开发人员设计了一个解决方案,该解决方案在很大程度上与 Maven 一样,在所有依赖项管理方面都有效,并且在那里也获得了同样的好处。
如果您使用 Java 进行开发,那么您可以设置一个本地存储库,然后使用maven或ivy + ant之类的工具来访问它。
您可以将本地构建工件的更新上传回您的本地存储库,因为它们已准备好供公司中的其他人使用。
对于其他开发环境,我不知道有哪些类似上述的工具可用——我倾向于将它们放在 SVN 中并完成它。
我通常使用单独的存储库来存储第三方库以将它们排除在常规开发存储库之外,并让我的构建文件将它们加载到相对于项目基本文件夹的预期位置。
实际上,我使用了两个存储库。一个用于构建我的项目所需的最小文件(例如,jar、lib 文件),另一个用于我通常存储 tar.bz2 的整个第三方包(包括源代码、文档或其他内容)。
这样,如果您只想获得构建东西所需的最低限度,您可以获取第一个存储库,如果您需要弄清楚发生了什么,或者如何使用第三方包,您可以开始提取东西出第二个存储库。
这不是理想的解决方案,但效果很好。
这是有关 svn 如何处理二进制文件的更多信息。
存储不是每个人都可以构建的二进制文件。我用 Verilog 和 VHDL 设计芯片,而软件团队没有这些工具。因此,我们将输出二进制文件存储在 SCM 中。
将二进制文件存储在 SVN 存储库中是完全可以接受的。作为旁注,我不明白为什么有人想在存储库中存储构建工件(我不是说你这样做)。
我会让我的构建和持续集成系统处理最新的工作版本,通过自动将它们复制到 FTP、Web 或文件共享以方便访问。
更好的是,我会投资一个自动处理构建工件的 CI 系统,我自己喜欢来自 jetbrains 的TeamCity,但还有其他人。这样您就可以全自动处理它。
在版本控制下存储二进制文件可能违背了版本控制的目的。你最好使用 HTTP/FTP .. 在https://stackoverflow.com/questions/104453/version-control-for-binaries上关于 SO 的讨论可能很有用!
至少我将二进制文件存储在 SVN 中,这样我可以快速恢复到特定版本的二进制文件并查看其中是否发生错误并跟踪引入错误的版本,而不是检查整个项目,设置所有特定项目相关和环境设置,然后编译它。
在这个问题上有一些争论,但我说是的。