你需要在多大程度上控制版本?

时间:2009-04-11 02:26:35

标签: svn git version-control

“磁盘”便宜的理论最近有点失控。版本控制的一些强大功能使我们能够使用一些引导文件和一个简单的命令来为新开发人员提供工具链。

最近系统的升级促使我们要求存储构建的二进制文件。接下来是对整个虚拟化构建系统进行版本化的请求。添加到顶层的每个层都会在存储库之间创建重要的关系,并且需要良好的基础设计来管理它。

工具链的存储带来了即时的好处,同时通过即时负债存储已构建的二进制文件。遗憾的是,在处理大型二进制文件时,Git存在一些基本问题。

您在哪里以正确的方式使用VC绘制线条,何时开始研究更合适的解决方案?

8 个答案:

答案 0 :(得分:11)

您可能不应该将“整个虚拟化构建系统”存储为巨型二进制文件。如果要对应用程序进行版本控制,则需要对源代码进行版本控制,而不是编译后的二进制文件。

许多商店在版本控制中存储步骤以重新创建构建服务器。然后你需要一个固定的图像(库存,开箱即用的OS安装),以及少量文件(在其上安装什么,以及如何安装)。有些地方甚至让他们的服务器在干净的操作系统安装中从源代码重建应用程序,以进行每次部署/重启。

将操作系统映像本身版本化为巨型二进制文件并不是那么有用。你不能分支。你无法合并。你不能差异。重点是什么?你可以节省空间,如果你的VCS可以做二进制差异,但这可能需要大量的CPU和内存,如果他们在“磁盘是便宜的”狂欢,那么没有理由让生活变得痛苦只是为了节省磁盘空间。

将安装脚本/库存储在VC中并根据需要重建VM映像,或者只将VM映像存储在普通文件中。我认为将图像放入VCS中没有任何意义。

答案 1 :(得分:8)

我会说这里有一个操作顺序:

如果需要存储文件,请使用文件系统。

如果他们需要跟踪更改,请使用版本控制。

如果他们需要跟踪与数据的关系,请使用数据库。

要求越复杂,解决方案就越复杂。但对于那些想要更复杂的解决方案的人来说,纪律是有道理的;在这些不确定的时期,必须避免浪费时间。

答案 2 :(得分:5)

我总是在版本控制中加入:

  • 源代码和makefile:构建二进制文件所需的最小值。
  • 测试套件

我从未在版本控制中添加:

  • 内置二进制文件:它们可以从源代码控制中重新创建,如果我知道我可能需要立即发布特定版本,我会以类似于Linux内核的方式将它们存储在文件系统中。

根据项目,我在版本控制中添加了什么:

  • 构建链:当我信任提供者或者我可以重新创建环境时,我不会将其置于版本控制中(Apple的Xcode,开源工具,如gcc或doxygen,......)。我把它放在版本控制中,当它专门用于项目时(例如,自制的交叉编译链),当我需要重新创建一个二进制文件时,就像它为交付而构建时(用于在任何组件可能涉及时找到heisenbugs,来自操作系统或编译器的代码。)

答案 3 :(得分:2)

对于相当极端的方法,请查看Vesta

来自Allan Heydon, Roy Levin, Timothy Mann, Yuan Yu. The Vesta Approach to Software Configuration Management

Vesta方法基于以下基础:

  • 所有来源和工具的不可变,不朽,版本化存储。不像 ClearCASE,Vesta使用显式版本号而不是视图。

  • 完整的基于源的配置说明。完成后,我们的意思是 描述将所有元素命名为构建。计算环境的每个方面,包括工具,库,头文件, 和环境变量,由Vesta完全描述和控制。通过 基于源,我们的意思是配置描述指定如何构建 一个只使用不可变源(即非衍生文件)的系统。 描述本身是版本化和不可变的源,以及它们 意思是不变的;特定的顶级描述总是使用相同的源描述完全相同的构建,即使在新版本之后也是如此 已创建来源和说明。

  • 自动派生文件管理。派生文件的存储和命名 由Vesta存储库自动管理,从而简化了 构建多个版本或构建多个目标平台的负担。

  • 所有构建工作的站点范围缓存。 Vesta具有共享的站点范围缓存 构建结果使开发人员可以从彼此的构建中受益。

  • 自动依赖性检测。 Vesta构建器动态检测和 记录所有依赖项,因此人为错误都不能忽略。通过动态,我们的意思是构建器检测实际使用的源 构建构建结果并仅记录依赖关系的过程 他们。 Vesta的依赖性分析没有利用任何知识 构建工具如何工作;因此,在Gunter [7]的术语中它是独立于语义的。例如,如果编译器在进程中读取文件foo.h 编译文件foo.c,Vesta将假定编译器的输出依赖 在所有foo.h上,即使具有C知识的工具也可以找到 foo.h中的各个项目可以在不改变结果的情况下进行更改 汇编。

答案 4 :(得分:1)

没有它就无法重新创建的版本控制。因此,工具链不能轻易地重新创建 - 在版本控制方面存在意义。使用版本控制下的工具链(和源代码),无需归档构建产品 - 或者至少在构建测试完成后不需要归档。

答案 5 :(得分:1)

常识,而不是IT烦恼,应指导您如何控制和配置工具链。如果您有标准硬件并且经常添加开发人员,那么将构建的工具链存储为图像是有意义的;但图像不必受版本控制。如果您有50个开发人员,则工具链的配置管理系统将减少开销;如果你有5个开发人员,那就是更多的开销 - 另一个需要学习的系统。

那么,Git是否妨碍了你想做的事情?或者你收到请求是因为用户试图说你应该让你的系统更复杂,因为你可以吗?

如果您的构建工具已经成熟,那么构建日期可能足以确定所使用工具的版本。您可以让构建脚本轮询编写构建工具及其版本的文本文件,类似于依赖项列表。

如果您正在使用快速更改的内部工具或正在开发的项目的alpha / beta版本,那么将构建工具置于版本控制之下会有一个很好的理由 - 但它会解决错误的问题。你为什么要使用不稳定的工具链?

答案 6 :(得分:0)

我坚持使用存储构建最终产品所需的任何东西的经典答案。不需要二进制文件和中间文件,但包含了构建中使用的任何脚本。

我使用我的git repos作为备份,在至少两个地方存储裸克隆,所以我尽量不留下构建所需的任何东西,但我不打算存储任何瞬态。

答案 7 :(得分:0)

我一直在为整个工具链使用源代码管理。如上所述,这有很大的好处:

  • 每个人都使用相同的工具,因此我们永远不必担心不兼容。
  • 构建计算机生成与开发人员相同的工件。
  • 我们总能在将来的任何时候重新创建任何工件,因为工具链是完全版本化的。

我在操作系统上方的某处画了一条线;我提交的一些内容是:

Linux的

  • GCC
  • 使
  • 的glibc

两个

  • JDK

我在尝试这样做时遇到的一些问题是:

  • 在Linux上,像Perl这样的东西,gcc将他们的安装目录嵌入到他们的可执行文件中。这意味着开发人员和构建计算机都有一个post-checkout脚本来运行,通过闯入二进制文件的路径来更新这些脚本。
  • 在任一平台上,您都有一个更长更复杂的编译选项列表来指定每个头和库目录;这种东西是自动的“正常”安装。其中一个不明显的事情是,crti.o和朋友是默认情况下在/usr/lib中找到的内容,实际上归glibc-devel(或libc6-dev)所有,所以除非安装了glibc-devel,否则它不在文件系统中。
  • 对于Windows,2003之后的编译器都使用Side-by-side Assemblies,所以为了避免在目标机器上安装过程,我不得不将它们挖出来并将它们放在源代码管理中的编译器可执行文件旁边。
  • 带有编译器的Windows SDK v6.1(没有帮助/样本)是巨大的:如果算起来的话就是427MB。

我已经开始尝试使用Apache Ivy(类似于Maven)来帮助我管理工具链,但我还没有看到任何常春藤或Maven用于管理工具的示例不是Java .jar文件。我不知道我是否能够管理像C编译器这样的东西。

理想情况下,我想要一个源代码管理结帐或Ivy或Maven解决方案,让开发人员的文件系统中的每个工具和库都可以使用。但是我开始认为要求开发人员安装少量关键内容,比如Windows SDK或gccglibc-devel软件包并不是一个坏主意。如上所述,这是一个由5或50名开发人员组成的问题,以及创建此类解决方案所需的时间。