谈谈源码管理那点事儿(一)——源码管理十诫(转)

引言:

 若是还有能够毫无偏见地涉及各个编程语言。比源码管理软件更必要的工具。我倒是非常想见识一下。

源码管理软件是我们工作的必备工具,是很多开发团队的血液。

那为什么我们都会对它有所误解呢?为什么都非常难理解版本号控制系统的核心价值和基本原理呢?

 原文作者总结出10条惯例(假设你愿意也能够用“戒律”)意味着必须服从它,并且一開始非常难理解。

它们与全部类型编程语言的版本号控制软件都有关联。在这里我选取了Subversion和.NET的几个样例,只是它们也广泛地适用于其它的一些技术。

英文原文:The 10 commandments of good source control management

  第一诫、假设你如今还在使用VSS,请立马停手

  它已经死了。

当然不全然对。它也存活了很多年,被全新的更有用的源码管理工具超越之后还在苟延残喘地活着。

准确地说当微软(还是会坚持一段时间的),它才是真的死了。

  平心而论。VSS还是一个不错的工具。

在1995年,它的光芒被像Subversion这样类似于Git和Mercurial的分布式软件给遮盖住了。

微软表示要代替它已经好多年了。

  原因是由于不支持现在的标准所导致的一系列缺陷使它一直不被看好。

众所周知它是微软的悲剧系统,但不知何故它能坚持这么久。虽然它有那么多小故障,缺陷,而且不包括必需的功能(相对于今天的标准)。

  第二诫、假设代码没放在源码管理软件里。等于它不存在

  每天反复读这句话——“使用源码管理软件是唯一的有效措施”。除非你在工作时使用项目的源码管理库来控制代码版本号——否则代码等于没有存在过。

  显然你曾发觉在你的本地机器上执行良好的代码在其它人那里执行的效果并不理想。是不是?他们不能获取你的最新版本号,他们没法去合并代码文件,你没有正确地部署它(參考you're deploying it wrong)并且假设你的SSD硬盘坏了的话,你将永远地失去你的劳动成果。

  仅仅要你保持这个心态——代码仅仅有提交后才是真的安全。才是其它良好编程习惯的保障。你能够把你的任务划分成很多非常小的单元以便你逐一提交。

你须要频繁地这么做。你就不必操心你的硬件会不会出棘手问题。

  只是更重要的意义是(至少对于你的团队领导来说),通过源码管理软件能够看到你做了什么。使用图表并列出项目清单是个好方法。只是怎么知道他们实际上在做些什么?而使用源码管理软件进行工作就能看得一清二楚了。

  第三诫、要早提交。常提交。而且不要认为麻烦

  关于前面那点,避免“幻影代码”(就是仅仅能在你的机器上看到的代码)的唯一方法是常常提交你的任务而且不要认为麻烦。

它能够解决你的问题,只是这样做也会对你的工作产生其它的影响:

  1. 每一个提交的修订都会为你提供一个还原点。假设你全然把代码搞砸了(没骗你,我们都这么做过)。你是希望恢复到一个小时前的工作还是一周前的工作?

  2. 合并文件时会出现的危急会随着时间不断添加。合并文件一直非常麻烦。

假设你不是每天都保持提交代码,某一天你会突然发现你和其它人的更改内容会有50多个冲突。你不会为此感到高兴的。

  3. 它促使你把任务分离成分散的单元。通常人们都是快完毕的时候才提交的,由于他们想把代码做成一个完整的逻辑单元模块。只是庞大的任务不可避免地要分离出较小的分散功能。而频繁地提交它们会使你更了解它们。你能够一个个地构建并提交。

  假设你做到这些,你的提交历史不可避免地開始类似于一种半规律的样式,里面每一个工作日都是在提交任务。当然不总是这样。也有停下来重构或測试,或者其它合理的活动也会中断标准的开发周期。

  然而。当我在看一个独立的——尤其是完整的项目时,每当发现我们在一个标准的开发周期里。有一天或几天什么都没有做,我便会很担忧。我之所以担忧是由于这意味着什么地方出问题了。一般不是有人正在想方设法要把问题搞定的话,就是由于卡在某个问题上而导致项目全然没有进度。不管究竟是什么情况,源码管理软件都会告诉你出现故障了。

  第四诫、提交前要检查你更改了什么

  往源码管理软件里提交代码的步骤事实上很easy(你恐怕会困惑上一条为什么说的那么麻烦)。一般仅仅要发现文件内容有变更时都会不顾后果地把文件传上去。像这样——“我的项目根文件夹下有文件内容变更了,我要快点提交上去!”

  如此会发生一件(或两件)事情:首先,程序猿会没有意识地把文件夹下的垃圾代码文件也上传上去。一些人看到类似以下的窗体时,就会点击“选择所有”然后提交——这样源仓库里就会被本不应该存在的未调试的文件和其它垃圾文件给弄乱。enter image description here

  或者是,程序猿实际上并没有检查他们更改过什么就把文件上传了。

当你在工作中处理配置文件或项目定义文件时非常easy就不经意把那些不想提交的文件给上传了,并且那些文件非常可能就被别的程序猿用到了。

你真的会记住你在配置文件中的全部更改吗?enter image description here

  解决方法非常easy:你必须在提交前立马检查你改过什么地方。做起来事实上比听起来还要easy。

使用很多系统已经提供的“忽略”特性能够大幅度地减轻“不经意上传文件”的危急。

你能够忽略Thumbs.db文件由于你压根不想上传它。

你在每次修订后可能还有其它文件不想上传——那么就忽略掉它们吧!

  至于文件中的更改,你通常能够使用某个流行的文本比較工具来观察差异。为什么我又要上传一次Web.config文件呢?enter image description here

  噢,我想起来了,我想把尝试password失败的最大次数从5次降低到3次。

啊,我差点没注意把一个虚拟的登录页面给上传上去了。这样的在提交前做检查的练习能够让你更easy理解下一节的内容。

  第五诫、写提交信息时一定要认真

  这是一个古老的谚语(出处不详),大意是说“写每一条提交信息时就好象等下会读到它的人是一个斧头杀人狂,并且他还知道你住在哪里”。假设我是那个杀人狂并在研究你的代码想追踪bug的话。看到的提交信息所有都是“代码更新了”,小心,我会来砍你的!

  我的解决的方法就是解释清楚为什么要提交新的代码。

每次你对代码进行更改都是有原因的。可能什么地方会崩溃。

可能客户不喜欢如今的主题颜色。

可能你只要调整一下构建配置。不管是什么。这都是有原因的并且你要把原因用文字保留下来。

  为什么?这样做的原因有非常多。并且在不同环境下各不同样。举个样例。使用“归属”特性或其它类似的功能显示出谁改了代码那些地方。假设我不记得18个月之前我对项目的Web.config文件改过什么地方或者我为什么要修改应用程序的设置,是由于我没有在当时留下一个适当的提交信息,而如今会非常easy:enter image description here

  这是一个能够随时观察代码更改的软件的一种。不管我像以下那样想了解一个文件的完整更改历史,还是仅仅想知道团队昨天做了什么,留下一个描写叙述性的相关记录意味着仅仅要不经意一瞥就能知道是什么情况了。enter image description here

  最后强调一下。当调试遇到错误时提交信息的重要性是无法预计的。举个样例,在你的集成环境里的最后更新的地方能够找到出错的原因。我的样例是非常显而易见的,只是把信息表示出来能够把非常多棘手的问题变得极好解决。enter image description here

  把这条牢记于心。这里列出一些提交信息的反面教材:

  1. 可恶
  2. 能跑了
  3. 攻克了一些混帐问题
  4. 攻克了
  5. 改进了一点bug
  6. 上传了
  7. 排字错误
  8. 修订1024

  好的,我从Stack Overflow站点的哪些是你写过的最差劲的提交信息(译者注:帖子已经被删除了,原因难道是出现了脏话?)帖子里选取了以上内容,只是它们和我曾经看过的提交信息并不同样。

它们没有告诉你有关代码更改的不论什么有效信息。它们都是垃圾信息。

  关于提交信息最后要注意的是;同一个程序猿之后提交信息绝不能和前面的全然同样。原因非常好理解:你向源码管理软件提交文件是由于对于上一个版本号的代码有东西改变了。你如今的代码和之前的已经不一样了,假设你的提交信息是完整准确的。理论上就不能和前面的同样。假设是同样的(可能有时真的会这样)。日志就会难以阅读。由于没有办法区分两条提交有什么差别。

  第六诫、你必须自己提交你的更改内容——不能托付他人

  听起来非常奇怪。但它的确会发生,我看过不止一次。近期的是上周。

情况是这种,源码库被视为极高的地位。

由于非常多原因。团队会去追求完美代码的洁净和单一。为了保持这种神圣的状态,代码仅仅能由某个领头的程序猿来提交。他在提交前会小心地整合,审查并(大概会)调整改善代码。

  即使站在非常远也能非常easy评价这个方法。不太频繁的提交(可能一周几次)。仅仅有一个脱离团队其它程序猿的人来提交,并且不可避免地在这段漫长的无提交时期里会有人的工作会导致项目混乱。

非常非常不好。

  这样做会有两个错误:首先,源码管理软件并不意味着它里面代码是神圣不可侵犯的。至少在整个开发周期里是这种。它应该是团队频繁整合文件,在出错时还原到正常而且共同解决这个问题的地方。不是自始至终都要这样做,仅仅有在应用程序周期的公布时期为了达到某种状态时才做的。

  还有一个问题——而且真的是极为关键的——站在程序猿的视角。这样等于你压根没有在用源码管理软件!它等于没有同伴之间的代码整合,没有还原。提交信息没有负责人,什么都没有!

你们不过在自己的象牙塔里各自写各自的代码然后等着未来顺便某一天把它交给领导就完事了。

  不要这样做。千万不要。

  第七诫、一定要管理好数据库的版本号

  这一点是我们都知道必需要做的,可是非常多人认为它麻烦。

问题是非常多(或者是大部分)应用程序没了数据库就不能执行。假设你没有管理好数据库,那你实际上做的就是一个不完整的全然没用的应用程序。

  差点儿全部的版本号控制系统的工作就是管理好文件系统内的文件。它仅仅是对像HTML页面。图片,CSS。项目配置文件和其它在文件系统的独立单元这类典型应用作用较大。问题是它确实没法在与程序有关联的数据库上起到作用。你总不能替换掉庞大的数据库,把全部旧数据文件和包括一大堆对象和数据日志文件统统换掉。这样会让版本号控制系统全然乱成一堆。

  Red Gate公司开发的智能的SQL Source Control使这个情况得到了合理解决。我在去年写的Rocking your SQL Source Control world with Red Gate这篇帖子里具体说明了这款软件,所以我如今就不多说了;总之就是数据库管理如今会很easy了!

  老实说,假设你没有管理好你的数据库版本号。你的开发会伴随着非常大的问题。

在更改数据库的时候没有源码的管理。没有还原点。而且非常难和团队密切合作。使用数据库版本号控制系统能够使开发更轻松。

  第八诫、编译生成的文件不要放进源码管理软件里

  简单地说:在编译执行项目时自己主动生成的结果文件不要放进源码管理软件里。对于.Net开发的程序猿,主要是"bin"和"obj"目录里一般会出现的.dll和.pdb文件。

  为什么?由于假设你这样做,你的同事会恨你的。

这意味着每当他们从版本号控制系统里取下最新文件时会让你的编译文件覆盖掉他们的。这是一个双重噩梦(你绝不能这样做)。在他们下一次编译时就会出问题。并且仅仅要他们又一次编译后再把编译文件又一次上传上去,相同的问题会以相反的方向再发生一次,只是这次你是受害者。你肯定不想这种。

  当然还有一个问题就是这样做非常浪费。这会浪费源码管理server的硬盘空间。会浪费带宽并会通过网络发送时一直潜伏着,并且这样做造成的不可避免的冲突会极度浪费你的时间。

  所以我们继续使用之前提到的“忽略”方案。仅仅要把像"bin"和"obj"这种路径直接忽略掉,一切就真的非常轻松了。仅仅要依照这个方案做一次。全部人都会感到开心的。

  事实上我在写pre-commit hooks时就说到了在版本号控制的server上不能提交此类文件。当然假设有值得这么做的原因的话,仅仅有这样的情况下你能够上传。只是我倾向于不要这么做以免将来会导致某个人在更新时发生冲突。

  第九诫、不要上传你自己的用户设置

  老实说,我觉得非常多人没有注意到他们把自己的私人设置文件上传到源码管理软件里了。

这样会出现的问题是:很多工具会产生仅仅管理你自己本地配置的文件。它们仅仅对你实用并且通常和其它人的私人设置文件相异。假设你把它们上传到源码管理软件里,非常快你就会覆盖掉其它人的私人设置文件。这样并不好。

  这是一个典型的.NET程序的样例:enter image description here

  假如你没有立马清理的话。多余出来的就是扩展文件和类型描写叙述,也就是.ReSharper.user文件和.suo(Solution User Option, 解决方式用户选项)两个文件。它们仅仅属于你,对其它人无效。

  为了理解这点,我们来看看ReSharper文件:

<Configuration>
  <SettingsComponent>
    <string />
    <integer />
    <boolean>
      <setting name="SolutionAnalysisEnabled">True</setting>
    </boolean>
  </SettingsComponent>
  <RecentFiles>
    <RecentFiles>
      <File id="F985644D-6F99-43AB-93F5-C1569A66B0A7/f:Web.config" 
caret="1121" fromTop="26" />
      <File id="F985644D-6F99-43AB-93F5-C1569A66B0A7/f:Site.Master.cs" 
caret="0" fromTop="0" />

  在这个样例里。不过在用户文件中记录了我启动了解决方式分析功能。

这不过针对我,我喜欢这个功能,其它人则不一定。

通常由于他们用的是老化的廉价的机子,我有点跑题了。

关键是我的设置会强制让其它人也运行。

我这么做不代表其它人也要这么做。

  (旁注:VSS不完美的地方主要在于ignoring .ReSharper.user files is a bit of a problem。能够看看这篇帖子)

  这个原理相同也适用于.suo文件。只是这里看不到里面的内容(它不是XML格式,而是二进制)。这个文件记录了解决方式浏览器的状态。公布设置和其它一些你不让强制用在其它人电脑的东西。

  所以我们要再次使用忽略方案来处理。

前提你如今用的不是VSS。

  第十诫、附属文件也要集成在一起

  这是十诫中的最后一条也是最最重要的一条。当应用程序须要外部的附属文件存在才干够正常执行的话,把那些文件也都放进源码管理软件里!人们倾向于犯的错误是,在他们拥有自己设置文件和本地附属文件的环境里一切都表现得非常好就把东西都上传了。之后认为没问题了就无论了。可是其它人不能从源码库里找到相同的附属文件的话。全部东西都会悲剧性地报错。

  我想到这点是由于今天从源码库里拖出某个旧项目并执行它时出现了这种画面:enter image description here

  我以为NUnit一直在机器上,但这次没有。

幸运的是使用NuGet能够高速解决这个问题,可是没有附属文件的话。不是每次都能够用相同的方式就能轻松解决的。

有些情况下,它们并非公开的。你非常难所有都获取到。

  我从源码管理软件里取出的项目执行时之所以会报错是由于我发现"C:\Program Files..."路径下丢失了附属的文件。

我花了不少时间用来联系最后更改过它的那个人(非常明显他在世界上还有一个非常远的地方),获取了那个文件,把它放进"Libraries"目录下并把它上传到了版本号控制系统里,这样下一个提取文件的人就不须要再这么麻烦了。

  当然还有一个重要的原因是。假设你在不论什么一种集成环境里工作时,你的构建server不一定安装了那些库。你必须有那些文件才干执行。Doug Rathbone近期写了一篇非常好的关于这点的文章Third party tools live in your source control(源码管理软件里的第三方工具)。并非非要那样做(我们也善意地评价了效果),只是它确实是一个非常方便的建议。

  因此推荐每一个人第一天就把程序执行所须要的东西全都放进版本号控制系统里。

  小结:

  没有哪一条是非常难理解的。老实说。它们都非常基础:尽快并频繁地提交,确认你提交的东西改了什么。还有东西一定要放进版本号控制系统里。解释清楚你的提交信息和确保是你自己提交的,不要忘记数据库和不要忘记附属文件。还有就是不要使用VSS:)

  总结:

  源码的科学有序管理,不论是对于个人还是团队还说都是极具价值的一件事情。如此重要的事情,我们该用什么工具来管理呢?请见一篇博客:《SVN—TFS,雷钟意bingo多点?》



posted @ 2017-07-23 16:47  lytwajue  阅读(274)  评论(0编辑  收藏  举报