您的项目的哪一部分应该在源代码控制中?


54

一位开发人员已经着手开发新的Drupal项目,并且sysadmin建议他们只应将sites / default子目录放在源代码管理中,因为它“将使更新易于编写脚本”。撇开这个有点可疑的说法,这又引出了另一个问题:哪些文件应在源代码控制下?是否存在应排除一些大文件的情况?

我的观点是,该项目的整个树都应受到控制,这对于Drupal项目,Rails或其他任何项目都是正确的。这似乎不费吹灰之力-您显然需要为框架编写版本控制,以及为编写的任何自定义代码所做的操作一样多。

也就是说,我很乐意就此发表其他意见。是否有任何理由不控制一切?


2
只要存储可行,任何生成最终表示形式的内容(包括文档)都应受版本控制。听起来好像在这里将代码生成与版本控制混为一谈,在此我将检查从您所版本控制的版本中轻松编写脚本(阅读:生成)更新的说法。
MrGomez

Answers:


71

我要说的是,源代码管理应包含的最低限度是重新创建项目的运行版本所需的所有文件。这甚至包括用于设置和修改任何数据库模式的DDL文件,而且顺序也正确。当然,要减去构建和执行项目所需的工具以及可以从源代码管理中其他文件自动衍生/生成的任何东西(例如,从源代码管理中的Java文件生成的JavaDoc文件)。


1
@EdWoodcock:没错,正确执行命令可能是一个真正的痛苦,但是有时候您想重新创建数据库的特定状态,或者在测试时选择应用某些更改,而不是删除/重新创建整个对象。我发现它因项目而异。
FrustratedWithFormsDesigner

1
要点是,这需要一定的水平或实用主义。
Ed James

3
@JayBazuzi:工作站安装指南(在源代码管理中)应概述必要的工具和依赖项,以及如何设置以及从何处获取工具。维护可用的工具箱重要,但这不是源代码控制的目的。我想,如果您真的想要,可以添加安装程序文件/.msi和一些说明文件,但这在某些工作场所可能不可行。您是否真的要将VisualStudio Pro 2010或IBM RAD,XMLSpy等签入源代码控制系统?许多工作场所已经控制了这些工具的部署。
FrustratedWithFormsDesigner

2
@artistoex:头发要分开了。通常假定build框与dev框具有相同的库。如果两者不同,则IT经理有问题。您(理想情况下)只需要源代码。在某些项目中,这不适用,但对于大多数项目而言,应该适用。
Mike S

1
@mike我是认真的。我认为实际上是肯特·贝克(Kent Beck)在有关XP的书中提出了这一建议。一个不错的主意。您几乎可以肯定100%能够重构所有构建因子。并且不要忘记环境在项目过程中最有可能发生变化。
artistoex 2011年

29

最好将几乎所有东西置于源头控制之下。

  • 图书馆

  • 资源资源

  • 构建/部署脚本

  • 数据库创建和更新脚本

  • 某些文件

  • 特定于环境的配置文件

唯一不应该放入源代码控制中的是项目的构建工件。


5
确保“某些文档”不依赖于特定工具。我遇到了许多项目,这些项目使用诸如SunOS Frame之类的东西来做文档,他们检入了所有“ .mif”文件,但没有检入生成的.ps或.pdf文件。现在,SunOS和Frame沦为历史的垃圾箱,许多设计文档仅以珍贵的纸本副本存在。
Bruce Ediger

2
@BruceEdiger在这种情况下,我个人需要输出和特定于工具的信息。如果该工具消失了,则您至少仍具有静态的电子副本:)
maple_shaft

这里的一个大公司的过程的优点之一,源进入VCS,产生的东西必须进入配置管理系统,所以即使你的工具已经被淘汰,你仍然有结果的控制
JK。

您使用的编译器的特定版本如何?哎呀,为什么不整个操作系统呢?
2011年

18

我会这样说;

  • 执行构建所需的任何文件都将进入版本控制
  • 构建生成的任何文件(可以)都不会

我倾向于将大型二进制文件(例如工具安装软件包)放在主干之外的某个位置,但它们仍应受版本控制。


15

并且不要忘记将所有数据库代码也都放入Source Control!这将包括原始的创建脚本,用于更改表的脚本(由使用它们的软件版本标记,因此您可以为任何版本的应用程序重新创建数据库的任何版本)以及用于填充任何查找表的脚本。


15

来之不易的经验告诉我,几乎所有内容都属于源代码控制。(我的评论在用专用硬件(有时很难找到)的专用硬件上为嵌入式/电信系统开发了十五年之久。)

这里的一些答案是“不要将二进制文件放入源代码管理中”。错了 当您使用包含大量第三方代码和大量供应商提供的二进制库的产品时,请检入二进制库。因为,如果您不这样做,那么在某个时候,您将要升级,并且会遇到麻烦:由于构建机器没有最新版本,因此构建中断。有人给新家伙要安装的旧CD;项目Wiki关于要安装哪个版本的说明过时;更糟糕的是,如果您必须与供应商紧密合作以解决特定问题,并且他们在一周内向您发送五套库,则您必须能够跟踪哪组二进制文件表现出哪种行为。源代码控制系统是一种可以完全解决该问题的工具。

这里的一些答案是“不要将工具链放在源代码控制中”。我不会说错,但是最好将工具链放在源代码管理中, 除非您拥有坚如磐石的配置管理(CM)系统。同样,请考虑上述升级问题。更糟糕的是,我在一个项目中工作,当我被录用时,有四种不同的工具链在浮动- 所有这些都在积极使用中!我要做的第一件事(在设法建立好工作之后)将工具链置于源代码控制之下。(建立可靠的CM系统的想法超出了希望。)

当不同的项目需要不同的工具链时会发生什么?举例:几年后,其中一个项目从供应商那里获得了升级,所有的Makefile文件都损坏了。原来他们依靠的是GNU make的较新版本。所以我们都升级了。哎呀,另一个项目的Makefiles都坏了。课程:提交两个版本的GNU make,并运行项目签出随附的版本。

或者,如果您在一个其他所有事情都无法控制的地方工作,那么您会遇到诸如“嘿,新人从今天开始,编译器的CD在哪里?”这样的对话。“ Dunno,自从Jack辞职以来没有见过它们,他是CD的监护人。” “呃,那不是在我们从二楼上楼之前吗?” “也许他们在盒子里或其他东西里。” 由于工具已经使用了三年,因此没有希望从供应商那里获得旧CD。

您所有的构建脚本都属于源代码管理。一切!一直到环境变量。通过在项目根目录中执行一个脚本,您的构建机器应该能够运行任何项目的构建。(这./build是一个合理的标准;./configure; make几乎是一样好的。)脚本应根据需要设置环境,然后启动构建产品的任何工具(make,ant等)。

如果您认为这工作太多,那就不是。它实际上节省了大量工作。您可以在开始时提交一次文件,然后在每次升级时提交文件。没有孤独的狼可以升级自己的计算机并提交大量依赖某些工具最新版本的源代码,从而破坏了其他所有人的构建。雇用新开发人员时,您可以告诉他们签出项目并运行./build。当1.8版具有许多性能调整功能,并且您需要调整代码,编译器标志和环境变量时,您要确保新的编译器标志不会意外地应用于1.7版补丁程序版本,因为它们确实需要代码随之而来的变化,或者您看到一些繁琐的比赛条件。

最棒的是,这将有一天节省您的钱:假设您在星期一发布产品的3.0.2版本。万岁,庆祝。在星期二早上,VIP客户致电支持热线,抱怨您18个月前发布的版本2.2.6中的超临界紧急漏洞。而且您仍然必须按照合同提供支持,并且他们拒绝升级,直到您可以确定该错误已在新代码中得到确定为止,并且它们足够大,足以使您跳舞。有两个平行的Universe:

  • 在Universe中,您在源代码管理中没有库,工具链和构建脚本,也没有坚如磐石的CM系统。...您可以签出正确的代码版本,但是它提供了尝试构建时会出现各种错误。让我们看看,我们是否在5月升级了工具?不,那是图书馆。好的,回到旧的库中,等等,有两次升级吗?嗯,看起来好些了。但是现在,这种奇怪的链接器崩溃看起来很熟悉。哦,那是因为旧的库无法使用新的工具链,这就是我们必须升级的原因,对吗?(我将为您省去其余工作的痛苦。这花了两个星期的时间,最后没有人高兴,不是您,不是管理层,也不是客户。)

  • 在一切都在源代码控制中的Universe中,您检出2.2.6标记,在一个小时左右的时间内准备好调试版本,花一两天的时间重新创建“ VIP错误”,查找原因,然后进行修复。当前版本,并说服客户进行升级。压力很大,但不比发际线高3cm的其他宇宙差。

话虽如此,您可以将其扩展到太多:

  • 您应该具有标准的操作系统安装,并且具有“黄金副本”。将其记录下来,可能在源代码控制的README中,以便以后的世代都知道版本2.2.6和更早版本仅基于RHEL 5.3和2.3.0构建,而以后仅基于Ubuntu 11.04构建。如果您通过这种方式管理工具链比较容易,那就去做,只要确保它是一个可靠的系统即可。
  • 在源代码管理系统中维护项目文档非常麻烦。项目文档始终领先于代码本身,在处理当前版本的代码时,处理下一个版本的文档并不少见。特别是如果您所有的项目文档都是二进制文档,则您无法进行差异化或合并。
  • 如果您有一个控制版本中使用的所有版本的系统,请使用它!只需确保整个团队之间的同步很容易,以便每个人(包括构建机器)都从同一套工具中获益。(我正在考虑像Debian的pbuilder这样的系统以及对Python的virtualenv的负责任使用。)

不要忘记签入任何难以更换的硬件。一家公司失去了构建,因为他们不再拥有运行构建工具的某些CPU(HPPA?68040?)。
hotpaw2

1
“ CM系统”代表什么?
bodo

1
在大多数情况下,我宁愿记录二进制文件和版本,也不愿自己提交二进制文件。是的-在您的情况下,二进制文件很难获得,并且您没有其他存储它们的好方法。但我觉得通常记录所有依赖项以及如何设置事物(例如dev VM)的工作量都相当轻巧。用脚本编写脚本可以改善复制,但是最终我们都必须交付。
Iiridayn

拒绝投票,是因为建议将工具链和构建工件放入源代码控制中。是的,如果您对这些解决方案的管理解决方案不佳,有时可能是必要的,但是绝对不希望如此。而且像PHP这样的流行OSS工具将始终可用(因为没有单个发布者可以消失),因此在当前问题中绝对没有必要。
Marnen Laibow-Koser

13

我没有置于源代码控制之下的唯一事情是可以轻松重新生成的文件或特定于开发人员的文件。这意味着由您的源代码,在源代码管理下通过读取/解析文件而生成的文档以及与IDE相关的文件组成的可执行文件和二进制文件。其他所有内容都进入版本控制并得到适当管理。


7

源代码控制的用例是:如果我们所有的开发人员机器和我们所有的部署机器都被流星击中怎么办?您希望恢复尽可能接近结帐和构建。(如果这太愚蠢了,您可以选择“雇用新的开发人员。”)

换句话说,除了操作系统,应用程序和工具外,其他所有内容都应在VCS中,而在嵌入式系统中,可能依赖于特定的工具二进制版本,我也看到过这些工具都保存在VCS中!

咨询过程中,我发现最普遍的风险之一是源代码管理不当-聘请新开发人员或安装新机器会带来各种磨擦。除了持续集成和持续交付的概念外,您还应该具有“持续开发”的感觉-IT人员能否基本自动地设置新的开发或部署机器,以便开发人员可以在完成之前先查看代码他们第一杯咖啡?


1
这也意味着在多台机器上进行工作非常轻松。只需拉回购,就可以开始了。
Spencer Rathbun

+1作为流星参考,可以很好地进行总结。
muffinista

有人可以指出一个示例,例如一个Java项目,其完整的工具链在rev控制下,以便可以直接检出并使用它吗?
andersoj 2013年

@andersoj退房boxen.github.com
拉里·


2

Drupal使用git,所以我将使用git的术语。我将对每个模块使用subrepos,以便能够从drupal的官方仓库中提取模块更新,同时仍保留各个部署的结构。这样一来,您可以获得脚本编写性的好处,而又不会失去将所有内容置于源代码控制之下的好处。


1

除以下内容外,所有内容均应受源代码控制:

  • 配置文件(如果它们包含针对每个开发人员和/或每个环境(开发,测试,生产)不同的配置选项)
  • 缓存文件(如果使用文件系统缓存)
  • 日志文件(如果要登录到文本文件)
  • 任何类似于缓存文件和日志文件的内容都会生成
  • (非常)大的二进制文件,不太可能更改(某些版本控制系统不喜欢它们,但是如果您使用的是hg或git,则它们不太在意)

这样想:团队的每个新成员都应该能够签出项目的工作副本(减去配置项)。

并且不要忘记也将数据库架构更改(每个架构更改的简单sql转储)置于版本控制之下。如果对项目有意义,则可以包括用户和api文档。


@maple_shaft在我关于注释中的环境配置文件的第一条声明中提出了一个重要问题。我想澄清一下,我的答案是针对问题的细节,这是关于Drupal或通用CMS项目的。在这种情况下,您通常具有本地数据库和生产数据库,并且一个环境配置选项是这些数据库的凭据(以及类似的凭据)。建议不要将其置于源代码控制之下,因为这会引起一些安全问题。

但是,在更典型的开发工作流程中,我确实同意maple_shaft的观点,即应该在源代码控制下控制环境配置选项,以实现任何环境的一步式构建和部署。


3
-1非常反对您关于不属于源代码管理的配置文件的声明。也许开发人员特定的配置文件是,但是如果您希望能够一步一步构建和部署任何环境,则必须使用特定于环境的配置文件。
maple_shaft

2
@maple_shaft在问题(重复项目或gereric CMS Web项目)的上下文中,“一步一步构建和部署任何环境”是极不可能的情况(您是否会将生产数据库凭据与所有内容放在一起?)。我在回答这个问题,没有提供有关应将版本控制在什么范围的一般指导。-但欢迎您提出
反对意见

在开放源代码的源代码存储库是公开的情况下,或者像金融机构一样,安全性是极端关注的问题时,我可以看到数据库凭证不属于源代码控制。除此之外,源代码管理还应受密码保护并限制于特定的用户集,因此,在这种情况下,源代码管理中的数据库凭据不应成为主要问题。您向我指出,反对票确实很苛刻,如果您编辑答案,我可以将其删除。
maple_shaft

@maple_shaft不用担心票数过低(我已经编辑了问题,但是如果您愿意,可以随时离开)。关于受密码保护的版本控制:最近,我们不得不处理一种情况,即笔记本电脑从我们管理团队的成员中被盗,其中包含我们版本控制系统的密码(当时装有我们的S3凭据)。从他的角度来看这是一个很大的诀窍(笔记本电脑没有密码保护,还有其他一些我无法真正透露的细节),但这仍然可能发生在每个人身上。基于这种经验,我们将所有内容都从vcs中移出。
yannis 2011年

@maple_shaft,尽管似乎我在提倡妄想症,但我们现在走到了极端,以保护与凭证相关的任何内容免受类似的困扰。
yannis 2011年

1

您的自动构建所做的任何事情都不会进入源代码管理。凡是要求没有生成过程中修改进去源控制。就这么简单。

例如,以下代码不在源代码管理中:

  • 生成的代码
  • 生成的二进制文件
  • 任何由您的构建创建的
  • 您的服务,流程,Web应用程序在运行时创建的任何内容

源代码管理中有什么:

  • 人类创造的任何东西
  • 另一个人或团体创建的任何内容(例如,分发源代码控制的第三方内部库或开源项目的二进制文件)。
  • 脚本和其他创建数据库之类的源(即,如果所有DBA都AWOL,您将如何重新创建数据库)。

这些经验法则是基于这样的观念,即源代码控制中的任何内容都可以被人类修改,并且可能花费某人宝贵的时间来了解其原因。


1

您需要工作并且可以更改的所有内容都需要以某种方式进行版本控制。但是很少需要有两个独立的系统来跟踪它。

通常,以可靠方式生成的任何内容都可以附加到源版本-因此,不需要独立地跟踪它:生成的源,未从系统传递到另一个系统的二进制文件等。

生成日志和其他可能没人关心的东西(但您永远不确定)通常最好由生成它的人进行跟踪:jenkins等。

从一个系统传递到另一个系统的构建产品需要跟踪,但是Maven存储库是实现此目标的好方法-您不需要源代码控制提供的控制级别。可交付成果通常属于同一类别。

剩下的一切(此时,应该只剩下源文件和构建服务器配置)就进入了源代码控制。


0

我的答案很简单:不是二进制文件。言外之意,几乎所有其他一切。

(但是,绝对不是数据库备份,架构迁移或用户数据。)


模式迁移绝对在源代码管理中进行。这样一来,您便知道代码需要什么数据库模式。
Marnen Laibow-Koser

0

源代码控制是一种变更跟踪机制。当您想知道谁更改了内容和时间时,请使用它。

源代码控制不是免费的。它增加了工作流程的复杂性,并且需要接受新同事的培训。权衡收益。

例如,控制数据库可能很困难。我们曾经有一个系统,您必须在其中手动将定义保存在文本文件中,然后将其添加到源代码管理中。这花费了很多时间,并且不可靠。由于它不可靠,因此您无法使用它来建立新数据库或检查更改时间。但是我们将它保留了多年,浪费了无数小时,因为我们的经理认为“所有事情都应该在源代码控制中”。

源代码管理不是魔术。尝试一下,但是如果没有增加足够的价值来抵消成本,则放弃它。


2
你是认真的吗?源代码管理不好,因为它需要对新同事进行培训?您实际上是在说您希望与不知道如何使用源代码控制并且不愿意学习的人长期合作吗?我个人宁愿倒汉堡。
Zach

嘿,我不是在反对源代码管理,只是反对盲目地对所有内容使用源代码控制。如果源代码管理具有非常复杂的工作流程并且没有增加价值,那么我宁愿不使用它。
2011年

2
我的观点是,即使您仅将它用于某些事情(咳嗽源代码cough),您的同事也应该已经知道如何使用它,因此在使用它们做其他事情时,培训他们的工作不应该增加开销。
Zach

0

我不会放入源代码管理中的东西:

  • 秘密密钥和密码
  • 即使SDK位于同一目录,并且如果我对SDK进行了修补,则也应将其设为另一个项目,因为它将基于每个框架而不是每个应用程序
  • 第三方库,例如。迁移,备份,编译后的代码,其他许可下的代码(可能)的剩余

所以我不做一个hg addremove例子,因为SDK更新时不时创建一个新克隆。这也使我每次SDk更新时都进行完整备份,并检查从存储库克隆的新版本是否正确。


0

我强烈建议您阅读以下有关您的担忧的书:

持续交付:通过构建,测试和部署自动化可靠发布软件。具体来说,第2章介绍了要放入源代码管理中的项目,正如许多人所说的那样,除了构建产生的大部分内容以外,实际上是所有内容。

我不同意@FrustratedWithFormsDesigner提供的一个公认答案,因为他主张不要将构建项目所需的工具放入版本控制中。源代码管理中的某个位置(与正在构建的代码相邻)应该是用于构建项目的构建脚本和仅从命令行运行的构建脚本。如果用他指的工具(即IDE和编辑器)来构建项目,则不需要它们。这些对于开发人员的主动/快速开发非常有用,并且这种环境的设置也可以编写为脚本,或者从SCM的另一部分下载,或者从某种类型的二进制管理服务器下载,并且此类IDE的安装应尽可能自动化。

我也不同意@Yannis Rizos关于在源代码管理中放置环境配置的声明。原因是您应该能够仅使用脚本就可以随意重构任何环境,并且在源代码管理中没有配置设置的情况下无法管理。没有将这些信息放入源代码管理中的各种环境配置如何演变的历史。现在,生产环境设置可能是机密的,或者公司可能不想将其放置在版本控制中,因此第二种选择是仍将它们放置在版本控制中,以便它们具有历史记录,并授予此存储库有限的访问权限。


-1

将所有代码置于版本控制中,并保留所有配置和用户数据。为了特定于drupal,您需要将所有内容置于版本控制中,但文件和settings.php除外

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.