良好的源代码控制管理十戒


  我还没有见过比源码版本控制这样跨任意编程语言更基本的工具。 这是我们用过的最基本的工具,是很多开发团队的生命线。 那么,为什么我们经常会用错呢? 为什么一些真正的核心,版本控制系统的基础往往知之甚少?

  我总结了10个实践 或“戒律” - 这通常是发生故障或错误理解的开始, 是与版本控制产品和编程语言无关的。 我会从Subversion和.NET挑选一些例子,但它们广泛适用于其他技术。

  1。 如果还在使用VSS,马上停手

  平心而论,在1995年VSS曾是一个伟大的工具。  不过因为有了像Subversion甚至分布式的如Git和Mercurial工具变得黯然失色。 很多年前微软已经明确表明废弃它了!

  由于一系列的重大缺陷,VSS曾受到广泛的几乎一致的鄙视, 俗称为微软的源代码破坏系统 。

  2。 如果源代码没有处在版本控制,那等于还没有

  每天重复此咒语 - “进步的唯一标准是工作代码处在源代码控制中”。 直到你的成果出现在源代码控制里 - 变成源控制库中的项目 - 否则它根本不存在。

  当然,你已经把代码做好在本地计算机上的某个地方,但,对其他人来说这不是真的做好了,对吗? 他们不能拿到你的版本,他们不能合并他们的修改,你无法部署它(除非你部署出错 ),一旦发生硬盘损坏你将永久丢失这些文件。

  你要保持除非提交否则根本还没有的心态,一大堆的其他良好的运作因为没有提交开始陷入困境。 你应将任务分解成更小的单位,这样你可以原子地提交。 您应频繁地整合,保证自己不受本地硬件故障的影响。

  但更重要的是(至少对你的团队领导来说),你证明你实际做了东西。 燃尽图曲线下降或分解列举任务列表是很棒的,但他们真的顺畅吗? 除非这些与工作源码控制中的工作代码关联上,他们才意味着完成。

  3。 尽早提交,频繁提交,越快越好

  继续上一点,只有这样,才能避免“幽灵代码” -那些只有你可以在你本地计算机上能看到的代码-要尽快地尽早地频繁提交到VCS版本控制系统里 。 上面提到的是应尽早和经常的完成提交,但其中有几点可以使你的工作方式有意义:

  1,每个提交的修订版能给你一个回退的位置。如果你完全搞砸了,你想回滚一个小时的变化还是一个星期的吗?

  2,合并噩梦的风险不会显着增加。合并从来就没有乐趣。 当你几天没提交代码时,你突然发现到你已经与其他人的变化有50个冲突,你肯定不开心。

  3,它会强迫你将功能隔离在分散的工作单元。比方说,你已经有了一个3人天功能需实现。 通常,因为他们想试图整个地构成一个逻辑单元直到这段时间结束才提交。 当然,像这样大的一个任务不可避免地由小规模,分散的功能组成,频繁提交迫使你识别这些原子小任务,然后逐一地完成它们提交给VCS。

  当你以这种方式工作时,你的提交历史形成一个有规律的模式,每天多次提交。 当然,并不总是保持这样不变的模式,有时我们停止开发和重构进入测试阶段,或任何其他中断正常的开发周期的活动。

  然而,当我看到一个独特的 - 甚至整个项目,在一个正常的开发周期,有整天甚至很多天什么没提交,我很担心。 我很担心是因为根据之前提到的,没有可衡量的工作已经完成,但我也很担心,因为这通常意味着出问题了。 这意味着,开发像“沸腾的海洋”那样进行(例如,试图一次做所有事情),或根本没有任何价值的事情在发生,因为在所有的人都阻塞在一个问题上。 无论哪种方式都是错的,源代码控制系统正打了个大红色警告。

  4。 在提交之前,请务必检查您所做的更改

  提交代码到源代码控制系统是很容易的 - 太容易了!无论如何,你总算了结了变更和提交了文件。 “在项目的根目录有一个变更地方 - 快 - 提交了!”

  可能会发生一件或两件事情:首先,人们在不经意间上传了一大堆的垃圾文件到存储库中。 请看类似下面的窗口,点击“全选”和确定 - 库不应该被某些文件如调试Debug文件夹和其他垃圾污染了。

  其次,提交文件经常不检查他们实际上已经改变什么。 例如在本地开发一次性修改的配置或项目定义文件,这使得它很容易在不经意间被放到资料库,原本不打算提交的,当然,他们很可能被其他开发者获取。 你真的能记住你改变了这个配置文件中的东西吗?

  解决方法很简单: 在提交之前你必须检查每一个变化 。 这听上去很容易,可使用很多版本系统实现的“忽略”功能,在很大程度上缓解“无意中提交文件”问题。 你不想提交Thumbs.db文件,只要忽略它,还有 你可能不想要提交的每一个变更文件!

  你经常想知道文件哪个地方修改了,为什么又提交Web.config文件?你可以使用VCS的文件比较Diff功能。

  啊,我现在想起来,我想减少最大无效密码尝试从5下降至3。 哦,我玩了一个假的登录页面,我绝对不希望提交到库中。

  5。 记得提交时编写提交信息日志,

  有了提交日志信息,我可以理解你的提交信息并可通过你的代码试图追踪一个错误。

  提交信息的整体思路是解释为什么你提交代码,每次你改变代码,肯定是有原因的。 也许是出了故障, 也许顾客不喜欢配色方案。 也许你只需要调整build配置。 不管它是什么,它是有原因的,你需要在你提交后留下它。

  为什么要写日志呢? 根据上下文的不同有几个不同的原因, 例如,使用“责备”功能,或其他类似的功能,它暴露了谁改变了什么以及意图 。 我不记得我在18个月前对这个项目中的Web.config改了什么,为什么我修改应用程序设置,因为我留下了不错的提交信息,这一切都变得非常简单:

  同样地,随着时间的推移变化,无论我是否希望看到的一个文件全部历史记录,如下图,我只是想看看昨天整个团队完成了什么,如有记录描述性的意见,意味着不需要采取更仔细的研究,就能了解这是怎么回事。

  最后,提交的信息是绝对无价的,当涉及到跟踪错误。 例如,想知道什么打断了持续集成环境。 当然,我的例子是明显而易见的,但有一点是,如果没有这个信息,这将是个棘手的问题。

  进一步考虑一下,这里有一些提交信息的反模式:

  1.有些事情。

  2.它的工作原理!

  3.修正了一些该死的错误

  4.修复

  5.修正一个小错误...

  6.更新

  7.错字

  8.修订1024!

  我是从Stack Overflow上问题挑选出来的——你曾经编写的最糟糕的提交信息是什么。 他们没有告诉你代码中实际发生了什么,他们是垃圾信息。

  关于提交信息的最后一件事, 来自同一作者的随后提交的信息不应该是相同的 。 原因很简单:你正在提交的原因与上一个版本不同。 你的代码与先前的版本是在一个不同的状态,如果你提交的信息是准确和完整的,应该在逻辑上是不相同的。 此外,如果是相同的(也许有一个合法的边缘情况下),日志变乱了,没有办法辨别两次提交之间的差异。

  6。 您必须自己提交更改 - 不能委派

  这听起来很奇怪的,因为,它发生过,我见过不止一次,最近一次就在上周。 这里的情况是源代码控制库被放置在控制台机器上。 由于种种原因,该团队将其视为隔离,完美的代码纯净环境。 为了维持这个神圣的状态,代码提交之前需经过小组评审并(推断)调整和改进后才能被首席开发人员提交。

  似乎这种模式是很有道理的。 但极少提交,多个开发人员团队只有一个作者,如果长时间没有提交的任何人一旦离开了即无可避免地将造成冲突混乱, 这样非常危险。

  有两个重要的事情错在这里:第一源代码控制并不意味着是无暇的,无问题的原始代码;第二没有贯穿整个开发周期。 源代码库是团队整合频繁的地方,当出错时可回滚,团队工作围绕的一个共同的基础。 在整个过程中并不一定是完美的,但它必须(尝试)在应用程序生命周期中的达成发布状态。

  另外,从开发者的角度来看, 这种模式是根本没有源代码控制!这意味着没有和同行集成代码,没有回滚,没有日志,什么都没有! 你只是坐在那里,在你的本地写代码,等待未来的任意点手工传给老板。

  7。 数据库版本控制不是可选的

  这是每个人都应该知道的,但很多时候,他们就是由于“很难”而没有做控制。 问题是,许多(大多数?)的应用程序没有数据库将无法运行。 如果你没有版本控制数据库,那么最终是一个不完整的应用程序。

  大多数VCS系统的工作原理是在文件系统上的简单地版本化文件。 例如典型的应用程序文件,如HTML页面,图片,CSS,项目配置文件和其他位于文件系统中的分散成小单元的文件。 问题是,这不是关系型数据库的工作方式。 相反,你面对的是这些大的数据文件和日志文件,其中包括一大堆不同的对象和数据。 当涉及到版本控制是相当混乱的。

  数据库版本有一些可用的工具,如来自Red Gate的非常优秀的SQL源代码控制工具。 去年我写了这个详细的文章——用Red Gate起舞你的SQL源代码控制世界,所以我不会再深入的细节,我只想说,现在数据库版本控制很容易!

  说实话,如果现在你没有版本控制那么在开发中你的数据库你正背着一个很大的风险。 进行更改时,没有一个单一的事实来源,没有回滚位置以及不容易和团队协作。

  8。 编译输出不应加入源代码控制

  注意:构建项目自动生成的任何结果不应该提交到源代码控制中。 对于的.NET人们,意味着几乎所有在“bin”和“obj”的文件夹的文件,这通常会是的.dll和.pdb文件。

  为什么呢? 因为如果你这样做,你的同事会恨你。 这意味着,每一次他们从版本库更新了变化,则直接用你的覆盖了他们自己的编译输出。 这将是一个合并的噩梦,而且可能打断下次重新编译进程。 然后一旦他们同样这样做重新编译和重新提交,整个该死的问题以相反的方向被重复,这个时候你是在接收端。

  当然,另一个问题是,它只是浪费版本控制机的磁盘,浪费了带宽和额外的延迟,这需要每次到发送它在网络上,并且浪费你每次不可避免的处理冲突的时间。

  于是,我们又回到了“忽略”的模式,前面提到的。 只要是“bin”和“obj”路径设置为忽略,一切都变得非常,非常简单。

  事实上,我甚至写了pre-commit钩子在VCS服务器上执行,只要是这样的内容,绝不会到放进源代码控制。

  9。 没有人在乎你的个人用户设置

  说实话,我觉得很常见地人们甚至不知道他们提交了自己的个人设置到源代码控制。 这里的问题是,许多工具会产生用于管理自己个人的,局部的配置。 这些只适用你,其他人通常会有所不同。 如果你把它们放到VCS,突然间,你都覆盖对方的个人设置。

  例如我在用户文件中启用方案分析,对我来说很好,我喜欢它,其他人却不。通常情况下,因为他们得到的是老龄化,极便宜的PC,但我却不。 问题的关键是,我不应该强迫其他人用我的设置 。

  .suo文件同样,里面没有漂亮的XML,该文件记录的东西二进制,如解决方案资源管理器状态,发布设置和其他你不想去强迫其他人的东西。

  10。 依赖关系也需要放进源码库

  当一个应用程序需要外部依赖才能成功地构建和运行, 把他们放到源代码控制里。问题是,人们倾向于在自己的小环境用他们自己的设置和本地依赖并使得一切工作好,然后提交一切到源代码控制里,甩手并认为是很酷。 然而,等到任何没有相同本地依赖可用的其他人更新后,一切都灾难性地失败了。

  我曾参与过一个项目工程假设NUnit在机器上,但这个时候,情况并非如此。 幸运的是伟大的NuGet解放我出来,但事情并不总是那么幸运, 当你开始发现缺少依赖时总是需要一番查找摆弄。 在某些情况下,他们没有公开可用,要试图跟踪这将是是彻头彻尾的痛苦。

  我曾碰到这种情况,我从代码库里检出一个项目,去运行它,发现缺少组件位于“C:\ Program Files......”路径。 我花了几小时试图追查谁最后成功运行它,然后组装起来,把它放在项目里一个“库”文件夹中,传到VCS。

  当然,如果你工作在任何类型的持续集成环境中,你的构建服务器要安装这些库。 道格·拉思伯恩最近他写了有关源代码控制里的第三方工具 。

  那么大家帮个忙,从第1天开始确保应用程序的构建和运行所需的一切都在VCS。

  总结

  说实话,这些事情都不难,真的都很基本:尽早并频繁提交,知道你正在提交什么,什么应该在VCS里,解释你的提交,并确保你自己亲自提交,不要忘了数据库,别忘记依赖。 但请忘记VSS。