【问题标题】:Is it acceptable/good to store binaries in SVN?在 SVN 中存储二进制文件是否可以接受/很好?
【发布时间】:2010-10-06 14:19:22
【问题描述】:

我们想共享运行时项目二进制文件。所以每个团队成员都可以使用当前的工作版本。 在 SVN 中存储运行时二进制文件是否可以接受/很好?

【问题讨论】:

    标签: svn version-control binary


    【解决方案1】:

    您可能希望将二进制文件存储在版本控制系统中的两个常见原因是(写于 2009 年):

    • 存储外部第三方库
      通常将它们存储到 Maven 存储库中,但将它们存储到 SVN 可以让您拥有一个且只有一个参考来满足您的所有需求:获取您的源代码,并获取您的您需要编译这些源代码的库。所有内容都来自一个存储库。

    (正如ivorujavaboy 在 2017 年指出的那样:“目前这样做的唯一充分理由是,如果您拥有永远不会改变的 STATIC 库,这是非常罕见的情况”)

    • 存储交付以加快部署速度
      通常交付(您构建以部署到生产中的可执行文件)是按需构建的。
      但是,如果您有很多预生产环境,并且如果您有很多交付,那么为组装、集成、认证、预生产平台构建它们的成本可能会很高。
      一种解决方案是构建一次,将它们存储在 SVN 的交付部分中,然后直接在不同的环境中使用它们。
      注意:
      这也适用于开发元素:如果您有一个生成 900 个 POJO 文件(通过 XML 绑定)的Jaxb 进程,并且您需要在多个环境中下载该开发集,您可能需要 1 个压缩文件复制事务,而不是 900那些。

    所以是的,出于正确的原因,“将运行时二进制文件存储在 SVN 中是可以接受的/很好的”。


    话虽如此:

    【讨论】:

    • 此外,如果您不能使用 Maven 或更喜欢 ant,那么将库存储在您的存储库中,以便轻松检查 ant 构建是有意义的。
    • 第三个常见原因是存储位图图形、音频和视频。这些也需要进行版本控制。同一视频的某些版本可能只适用于使用它的源代码的某个版本。
    • @Rob:a/ 如果它们经常更改,b/ 如果您需要检索旧版本,那么可以。如果没有,其他存储库(不基于 VCS)如 Nexus 将确保这些元素的一些历史记录,并且您将能够比在 VCS 中更容易地从所述存储库中删除它们。
    • +1 介绍 Nexus,我应该自己探索这个想法。
    • @ivoruJavaBoy 我同意。这是 8 年前在另一个时间写的;)让我编辑答案。
    【解决方案2】:

    不,不要将二进制文件存储在其源代码旁边(除非您有充分的理由来弥补缺点)。

    缺点:

    • 它鼓励大型项目中的不良构建实践。最佳实践是完全自动化您的构建。提交二进制文件使您可以忽略这一点:“只需手动为已更改的部分进行构建”:-(
    • 更新和提交速度较慢
    • 更改源代码但未更改相应二进制文件的提交会引起开发人员的混淆。您如何检测到不匹配?
    • svn update 将更新您的二进制文件的时间戳,从而混淆您的构建工具,从而错误地认为二进制文件比您的源代码更改更新。
    • 导致svn updatesvn merge 的二进制文件出现虚假冲突
    • 它使用存储库中的更多磁盘空间。 (根据您的项目,这可能可以忽略不计。)

    通常,避免提交从其他版本化资源以确定性方式自动生成的任何内容。没有冗余 -> 没有出现不一致的机会。

    相反,使用持续集成服务器在每次提交时自动重建(并运行测试)。如有必要,让此构建服务器在某处(SVN 之外)发布二进制文件。

    现在,这并不意味着您应该将此作为绝对规则或避免所有二进制文件。无论如何,将您的构建工具和第三方闭源二进制文件放入您的项目中。并在有意义的时候做出例外。理想情况下,新开发人员应该能够检查并立即启动构建脚本,而无需花费一两天时间来设置他的环境。

    【讨论】:

    • “相反,使用持续集成服务器在每次提交时自动重建(并运行测试)。如有必要,让此构建服务器在某处(SVN 之外)发布二进制文件。” ...我假设 CI 会从源代码控制中提取它需要的东西 - 所以我们不是处于先有鸡还是先有蛋的情况吗?
    • 忘记那条评论 - 我重新阅读了这个问题,并注意到他们在询问是否应该将构建中的“输出”存储到源代码控制中。我从“我们是否应该在源代码控制中存储二进制依赖项”的上下文中查看它(以及您的答案)
    【解决方案3】:

    如果您使用 Java 进行开发,那么您可以设置一个 local repository,然后使用 mavenivy+ant 之类的工具来访问它。

    您可以将本地构建工件的更新上传回本地存储库,以供公司中的其他人使用。

    对于其他开发环境,我不知道有哪些类似上面的工具可用——我倾向于将它们放在 SVN 中并完成。

    我通常使用单独的存储库来存储第三方库,以将它们排除在常规开发存储库之外,并让我的构建文件将它们加载到相对于项目基本文件夹的预期位置。

    实际上,我使用了两个存储库。一个用于构建项目所需的最小文件(例如 jar、lib 文件),另一个用于我通常存储 tar.bz2 的整个第三方包(包括源代码、文档或其他内容)。

    这样,如果您只是想获得构建所需的最低限度的东西,您可以获取第一个存储库,如果您需要弄清楚发生了什么,或者如何使用第三方包,您可以开始从第二个存储库中提取东西。

    这不是理想的解决方案,但效果很好。

    Here 是关于 svn 如何处理二进制文件的更多信息。

    【讨论】:

      【解决方案4】:

      存储不是每个人都可以构建的二进制文件。我用 Verilog 和 VHDL 设计芯片,而软件团队没有这些工具。所以我们将输出的二进制文件存储在 SCM 中。

      【讨论】:

        【解决方案5】:

        正如许多人已经说过的,这是可以接受的。

        是的,将所有东西都放在一个位置很方便,您可以从那里(例如)签出已以二进制形式存在的旧标签及其正确的依赖关系。

        但是不是好,尤其是用于备份目的。我们将所有二进制文件(和部分依赖项)存储在 SVN 中,并且随着项目的增长,二进制部分也是如此。

        不幸的是,svnadmin dump 只是转储所有内容,您无法指定要排除的存储库路径。因此,备份(和升级 svn 服务器)变得非常痛苦!

        如果您在我们的案例中添加这些二进制文件在不久之后不再有用,我敢肯定我不会在类似的情况下再次这样做(但我会为较小的项目做)。

        因此,我建议您在这样做之前三思而后行,并尝试预测您能发展到多大以及可能发生的其他情况。

        【讨论】:

          【解决方案6】:

          每当我在 Subversion 目录中看到库时,我都会问以下问题:

          • 它是什么版本? (通常你有axis.jar 而不是axis-1.4.jar
          • 为什么包含它? (尤其是依赖项的依赖关系)

          如果您没有适当的依赖管理系统,您通常无法回答这两个问题。这是通往 Jar Hell 的第一步。

          我可以推荐带有 Intranet 存储库的 Apache Ivy(其他人可能对 Maven 发誓)。使用 Ivy,我不必将库存储到 SVN 中,并且总能回答上述问题。

          【讨论】:

            【解决方案7】:

            至少我将二进制文件存储在 SVN 中,这样我可以快速恢复到特定版本的二进制文件并查看其中是否发生错误并跟踪引入错误的版本,而不是检查整个项目,设置所有特定项目相关和环境设置,然后编译它。

            【讨论】:

              【解决方案8】:

              我们的 Java .jar 文件构建绑定在它们的 .jar 文件依赖项中,我们正在将其检入 svn。很多这在实践中是多余的,但我们希望确保我们生成的每个 Java 应用程序构建都准确地包含用于进行 QA 的库。

              然而,真正让我恼火的是,当我开始远程连接到存储库并进行同步时,这种方法。翻遍所有的二进制库需要很长时间。

              我们已经放弃了这种做法,现在使用 Maven 来管理库依赖项——即使对于我们仍在使用 ant 构建的项目也是如此。没有更多的二进制文件被检入 svn。由于这种战略转变,生活在多个方面都好得多。而且我们可以严格控制所需的库依赖版本。

              对于我们的 .NET 构建,我的一位开发人员设计了一个解决方案,该解决方案在很大程度上与 Maven 一样,在所有依赖项管理方面都能发挥作用,并且在那里也获得了同样的好处。

              【讨论】:

                【解决方案9】:

                在版本控制下存储二进制文件可能违背了版本控制的目的。你最好使用 HTTP/FTP。https://stackoverflow.com/questions/104453/version-control-for-binaries 上关于 SO 的讨论可能有用!

                【讨论】:

                  【解决方案10】:

                  我会让我的构建和持续集成系统处理最新的工作版本,通过自动将它们复制到 FTP、Web 或文件共享以方便访问。

                  更好的是,我会投资一个自动处理构建工件的 CI 系统,我自己喜欢来自 jetbrains 的 TeamCity,但还有其他人。这样你就可以全自动处理了。

                  【讨论】:

                    【解决方案11】:

                    是的,保存它。

                    我们过去将交付给客户的二进制文件存储在 SVN 存储库中以跟踪它。

                    将二进制文件存储在 SVN(或源代码控制)中的另一种用途是,如果您向公司中不想构建您的项目的其他团队提供一些内部实用程序模块以节省他们的构建时间。我相信这是一种常见的做法。

                    但我们从不允许存储 Eclipse 的 .classpath 和 .project 文件(工作区相关设置)。

                    【讨论】:

                    【解决方案12】:

                    不是为了这个目的,不。您应该使用外部文件存储,例如 FTP 或 Web 服务器。这样就可以轻松下载特定版本的运行时二进制文件,而无需先在 SVN 中更新到该版本。

                    【讨论】:

                      【解决方案13】:

                      我想说,如果它能让你的团队生活更轻松,那就去做吧。如果它减少了设置工作开发环境所需的时间,那就去吧。

                      【讨论】:

                        【解决方案14】:

                        在这件事上有一些争论,但我说是的。

                        【讨论】:

                          【解决方案15】:

                          在 SVN 存储库中存储二进制文件是完全可以接受的。作为旁注,我不明白为什么有人想要将构建工件存储在存储库中(我不是说你这样做)。

                          【讨论】:

                          • 我们有一两个很少改变的小程序,而且编译起来绝对是个麻烦,需要一个专门的环境和你有什么。为了简单/理智,我们将它们存储在 SVN 中。
                          • 实际上,现在我想起来了,我们也有一些无法在命令行上或以自动化方式构建的工件,我们经常在是否值得将它们放入的问题上犹豫不决存储库 (SWF
                          猜你喜欢
                          • 2021-07-25
                          • 2017-04-27
                          • 1970-01-01
                          • 1970-01-01
                          • 2011-02-02
                          • 2012-05-26
                          • 2018-04-17
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多