[敏捷]为什么我们选择Mercurial

五 12th, 2011

不管你是开发人员或者是测试人员,我们每天都会接触到版本管理工作,不管你用的是什么版本管理软件,它不可能跳出下面的三中类别。

  • VSS :一种加锁模式的版本管理工具,并不支持并行开发的模式。
  • SVN/CVS/TFS: 属于合并模式的版本管理工具, 支持并行开发,但是支持的并不好。我们一般称之为集中式版本管理工具。它最大的特点在于它的Repository(仓库),这类工具提供了一个唯一的Repository,所以用户进行的commit或update以及其它的相关操作都需要连接到该Repository才能进行。
  • Git/Mercurial/Bazaar: 这些都是属于分布式版本管理工具(DVCS),支持并行开发, 同时也提供很多很好的特性来支持并行开发模式.
    这里,我相信大家应该都用过SVN/CVS/TFS中的一种或几种(VSS应该没多少团队会用了,真的很不方便),或多或少对版本管理工具有过一些了解,所以在理解分布式版本管理工具的时候可以参考使用SVN/CVS/TFS的一些经验。下面,我主要是以SVN和Mercurial为代表来对比集中式版本管理和分布式版本管理。

集中式版本管理(SVN)

据不完全统计,现在使用SVN作为版本管理的团队还是占大多数。据我了解,像豆瓣,腾讯,淘宝都有很多团队都在使用SVN,目前我所在的团队也是一直在使用SVN。我们都在使用并不代表它就够完美,就拿我们团队来说,碰到过很多的问题。下面我就将我们团队在使用SVN的过程中,碰到不方便的地方总结下来。

  1. 加班写代码,但是代码一直都存在问题,要么编译不过,要么测试代码不能通过。这个时候,时间已经转向了午夜12点,你能怎么办?选择将这样的代码提交到Repository,还是继续留在本地?我相信大多数的开发团队都会禁止提交不能编译通过的代码或不能测试通过的代码。如果这样持续下去,你会发现几经修改的代码其实从来没有做过版本控制。
  2. 在离线状态下,没法进行的commit或update以及其它的相关操作。导致在家,在旅途中等离线环境下所做的工作没法进行版本的控制。
  3. 某人写了一个模块,总是有 bug 没有修改完,而不敢提交。这个时候,另一个人希望协助他找问题,却没有合适的途径 share 那段完成了一半的模块。跑过去 XP 一下么?天哪,为什么我们这里每个人用的编辑器都不一样,还都爱用些特别个性的配色方案呢?
  4. 如果有些模块由两个人合作编写,那么他们之间的关系非常紧凑。有时候需要在两人之间交换一些代码,有时候我们为了方便,就直接通过代码仓库(Repository)中转,结果在仓库中留下许多未完成的版本。
  5. 在团队协作开发模式中,大家同时对一个模块进行修改,导致变更冲突有很多,这时候处理起来会比较麻烦。SVN的Merge功能实在是很弱,你懂的,我不多说了。
  6. 最让人恶心的一个功能,虽然不影响使用。那就是SVN会在工作目录里创建一个隐藏目录记录本地状态信息。
  7. 上面的场景,你是否碰到过了?其实我相信大多数人都会碰到其中的一些场景,也肯定有用一些插件或者用某些技巧绕过这样的场景。

好吧,我承认我也有想过解决的办法,但是效果并不明显。当我接触了微软内部的一个分布式版本管理的工具之后,我才发现原来我一直追求的就是它—DVCS。后面我会展开来谈谈分布式版本控制工具的一些功能和特点。并插入一个Mercurial实例,让你明白如何利用Mercurial来进行版本管理工作的。

分布式版本管理(Mercurial):

吼吼: 分布式版本管理,提供了强大了仓库合并的功能,让开发者可以在离开中央仓库的情况下还可以享有全部的版本管理功能。

我们先看看版本管理相关的几个概念,要是早就知道的可以跳过这段,没必要再看了:

repository:版本控制系统中的 repository 就像一个仓库一样,用来存储被管理的数据文件,包含数 据文件的不同版本。一般会有一个所有用户都可以访问得到的 repository 保存了项目的“主要”版本,工作repository 是用户自己做事情的地方.

Revision: 在使用Mercurial的系统中每个改动隔离在各自的repository里,既避免把不相关的代码混杂起来,又便于一个接一个的测试每一部分工作,用户做的每个改动称为一个revision.用户在自己工作版本上实现新的特性,修改漏洞,重构,实验等,当完成改变后,你可以 push 到共用的 repositor y中,即完成了一个 revision。

Changeset:一个或多个文件的改变集合在一起形成一个逻辑单元,称为 changeset。每一个 changeset由两部分内容描述,版本号和 changeset 标识,例如: changeset: 207:58e4906e69e3 冒号前面的数字代表版本号,它用来标识本地 changeset。这个版本号只有在用户的本地repository 中才有意义。

Head:Head 表示 repository 中每个分支最新的 revision,通常在合并几个分支时会用到这个概念。

Tip :Tip 是最新的一个 changeset 的版本号的一个别名。在命令中任何使用版本号的地方都可以使用 tip 来代替最新的 changeset的版本号。Tip在各个repository中是不同的,同时一个repository 中只有一个 tip。

Log :Log 命令按时间顺序从近到远的记录着在 repository 中发生的每一次事件。可以通过指定-v诊断输出选项来获得更多更详细的历史信息,或者指定—debug选项来获得历史信息中的一切细节。

注: 分布式版本管理工具与传统的版本控制系统对于repository的概念是有差别的:

  • 传统的版本控制系统中,这样的repository 是集中式的。除了这样一个集中式的 repository 之外,每个用户会有一份自己的工作版本拷贝。用户通过命令同步自己的拷贝和集中式的repository。传统集中式的管理中,只有一份 repository,其他的只是工作拷贝,不包含额外的版本。
  • 分布式版本控制系统中的 repository 则采用的是对等网络式的方式。分布式的管理当中,每个用户所持有的都是一个真实的 repository,当中存储有不同的版本信息和维护一个 repository 的必要的辅助元数据。这样一个对等工作模式当中,用户通过交换下文即将提到的 changeset 来完成同步。

clip_image001

正是因为这个repository的差别,才有了分布式管理的重多优点。

分布式版本控制相对于传统的版本控制系统的优点:

  • 更轻松的管理

    传统的版本控制系统使用集中式的 repository,一些和 repository相关的管理就只能由管理员一个人进行。由于采用了分布式的模型,Mercurial 中就没有这样的困扰,每个用户管理自己的 repository,管理员只需协调同步这些repository。

  • 工作的并行度将大大的提高

    每个用户都可以带着这样的repository,从这里他可以把当前的工作拷贝切换到 repository 里面存储的任何一个版本。这个版本可以是之前正在工作的版本,现在需要合并进一些别人的意见,也可以是用户私有的一个版本,当前正在做很多前瞻性的工作,还没有能同步给其他用户使用。也同样是因为这样的模式,每个用户可以任意把自己的 repository 当中的一个版本交换给其他用户,而不需要对自己手头正在工作的版本进行回退。

  • 快速可靠,更健壮的系统:

    a. 由于DVCS的工作目录与中央仓库(Central Repository)别无二致,同样保存了全部的元数据,而Subversion需要通过网络完成的操作(诸如提交、追溯历史、更新等), Mercurial在离线条件下通过操作本地仓库完成.

    b. 在中央仓库出现问题,我们依然可以通过备用仓库交换修订,日常工作在没有中央仓库的情况下依然可以正常开展。当中央仓库修复之后,所有的修订可以通过备用仓库同步到中央仓库上。避免了使用CVCS时将“所有鸡蛋放在一个篮子里”的风险。

    c. 分布式系统比集中式的单服务器系统更健壮,单服务器系统一旦服务器出现问题整个系统就不能运行了,分布式系统通常不会因为一两个节点而受到影响。

  • 便于协同工作

    a. Linux 平台下开发完功能之后,并在windows的工作目录指向Linux工作站,获取更新. 验证windows平台之后,如果有问题,将windows工作站的修改提交到Linux工作站,最终Linux下验证并同步到中央仓库. Mercurial的分布式特性让开发团队敏捷的分享修订,更有效率的开发。

    b. 代码库庞大而且网速缓慢,克隆中央仓库的操作需要花费数小时才能完成的情况下,Mercurial的灵活性使我可以将工作站指向已经存有代码的笔记本电脑来执行克隆操作, 数分钟后工作站就完成了全部的克隆操作,之后再将它指向中央仓库,即可正常提交/更新代码,大大节省了时间,提高了效率。

  • 对小步前进友好

    本地仓库的存在,使Mercurial对小步前进更加友好 。小步前进意味着开发者在不破坏任何现有功能的前提下,每次修改少量代码并提交。

  • 学习曲线低

    Mercurial的基本命令与CVS/Subversion非常类似,熟悉CVS/Subversion的团队可以依然工作在熟悉的命令行环境。从结构到命令,Mercurial做到了对CVCS用户友好,降低了学习曲线.

    当然,我们也不能忽略Mercurial其它的优点,比如说它能支持SSH方式的push,它是基于安全的通讯协议并且使用系统的用户管理机制,在保证安全性的同时保持了使用上的简单性。 同时,它只在工作目录(本地Repository)的顶层生成一个隐藏目录,这样就可以保持工作目录的清爽。

  • 上述这些并不代表全部,其它的优点就让我们在使用中慢慢体会吧……

综上,DVCS天生是为了哪些开发者在地理上极度分散的,但又需要对源码进行有效的版本管理。同时对于一般的软件项目来说,DVCS也同样是个好东西,特别是其变更合并功能和分支管理功能。

这篇文章是我对分布式版本管理工具的一点总结。希望你能从这篇文章中找到你想要的东西。

后面,我会接着完成下面2篇文档:

Mercurial操作指南

Mercurial扩展

参考资料





    除非注明,本站文章均为原创。本文基于 BY-NC-SA 协议进行授权,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 metaboy(包含链接).

    本文链接地址: http://blog.wangyuxiong.com/archives/51135

    订阅本站:http://www.wangyuxiong.com/feed

    分类: 工具推荐         标签: , , ,
    1. Sac Vanessa Bruno
      七 23rd, 201301:09

      What’s up, I check your new stuff daily. Your story-telling style is awesome, keep up the good work!

    2. admin
      五 12th, 201122:57

      占用的空间的确会有所增加,但是却不明显。它会存储不同版本的元信息,一般都是以二进制的形式存储,相对比我们的源文件,它的增加是微不足道的。
      @w*g*n

    3. w*g*n
      五 12th, 201111:23

      谢谢,很好很强大!
      但有些疑问:本地就是自己的一个仓库,那久远以后,占用的空间会不会越来越大?

    无觅相关文章插件,快速提升流量