« 周末过了两天黑白颠倒的日子 | 返回首页 | 版本控制系统再考察 »

分布式的版本控制工具

我最早接触的 SCM 工具是 vss ,但是没用几天(换工作到网易后)就迁移到了 cvs 。我自己大约用了一年后,公司集体从 cvs 迁移到了 svn 。领导这次大迁徙的大大说, svn 是一个更好的 cvs (确实是这样吗?据说有争议,但至少我感觉在多文件版本控制上 svn 比 cvs 方便,因为 cvs 无法保证多个文件同时提交的原子性)。

前几年,有人跟我争论过到底 vss 的加锁模式好,还是 cvs 的合并模式好。我觉得答案是不言而喻的,懒得争论。虽然在某些特殊环境上,我们偶尔需要加锁模式协同工作,但对于程序员的协作来说,无疑我们需要并行的工作。

我们在若干年前曾经淘汰过一次加锁的协作编码方式,而到了今天,是时候再做一些改变了。或许,分布式的版本控制工具才是未来的发展方向。我想,总有一天,cvs/svn 这类集中式版本控制工具会被淘汰掉的。

说说我的困扰吧,可能很多开发小组也遇到过。

  1. 我们禁止提交不能编译通过的代码,尽量不提交不能测试通过的代码。结果,对于很复杂的模块,有人几乎一个月都没提交过一次。他总是觉得程序还不太成熟,但几经修改的代码其实从来没有作版本控制。

  2. 有些模块由两个人合作编写,关系非常紧凑。有时候需要在两人之间交换一些代码,为了方便,大家通过代码仓库中转,结果在仓库中留下许多未完成的版本。

  3. 代码被用笔记本带回家,结果在家完成的部分无处可以提交。(为了安全,我们的代码仓库不能从外网访问)

  4. 某人写了一个模块,总是有 bug 没有修改完,而不敢提交。这个时候,另一个人希望协助他找问题,却没有合适的途径 share 那段完成了一半的模块。跑过去 XP 一下么?天哪,为什么我们这里每个人用的编辑器都不一样,还都爱用些特别个性的配色方案呢?

我们尝试过一些 work around 的解决方法,比如在本地自己创建仓库。托 TortoiseSVN 的福,这件事在 Windows 下做起来还是很简单的。可终归是多个仓库的管理,用的人始终感觉麻烦,而没有贯彻下去。

今天有同事问我,分布式版本控制工具到底跟我们现在在用的系统有什么区别。我想了一下回答说:它的本质就是在原有工具的基础上增加了一种方便的仓库合并功能。(哈,我接触这类东西时间不长,大家就当我胡说)

集中式版本控制工具,总要求你有一个中心服务器,提供一个项目仓库。每个人都必须严格保持跟仓库的内容一致。当项目大于等于 2 人时,往往都会指定一些规则,比如不要提交写了一半的代码到仓库去等等。结果,这些规则导致了上面我提到的问题。

即使是一个人自己用,有时候也会碰到问题。有一次我回到家,看到老爸(一个老程序员)在家做一个自己的小东西。因为我们家有两台电脑,我看见两台机器上有若干份不同的版本,我便推荐他用 svn 。因为两台机器都不是 24H 开机,我便选择了在 U 盘上创建仓库。可以设想的到,两台机器的 U 盘插入后盘符是不同的,这可真是一场灾难啊。

其实大多数情况下,我们要的仅仅是 版本管理 ,并不要求通过这类工具协同很多人修改同一份代码。在我们公司,修改别人的代码是要通知文件创建人的。大家都尽量在自己的工作目录下写东西。我并不要求分布式的版本控制工具帮我解决开发人员分布在不同地方的问题,我需要的仅仅是可以更方便的创建私人(或小团体)的分支,可以局部的提交的问题。这些,只需要一个仓库合并的特性就做到了。


我比较孤陋寡闻,知道有分布式版本控制工具是从 git 发布的消息开始的。有 Linus 的鼎鼎大名在那,应该是个好东西。我想还会有一些跟我一样,一进入项目开发就两耳不闻窗外事的朋友,不知道 git 是何物的话,不妨看看 Git 中文教程

可惜的是,git 对 Windows 支持的并不好。我们至少还有一半的项目跑在 Windows 下,开发人员则超过一半在用 windows 平台。听说其原因是 git 非常依赖文件系统的一些特性,这些在 Linux 下表现的很好,而 Windows 下特别糟糕。不管具体原因是这个还是别的,我对在公司推广 git 没有多少信心。

另一个选择是 Monotone ,但听说跟 git 有同样的问题(对 windows 的支持问题)。毕竟 git 本身就受了 monotone 的很大影响吧(我猜的)。有趣的是,和 Git 一样 Monotone 也是用 C 写的。当然这句话其实应该倒过来说,因为 Monotone 是从 2003 年开始的,比 Git 早多了。

关于 Git 和 monostone 对 windows 支持不太好的说法,可以参考这一篇: Mozilla: Version Control System Shootout Redux Redux ,Mozilla 的大大这样评价:Git is inappropriate for cross-platform projects due to its UNIX-centric nature; same goes for Monotone.

嗯,既然 Mercurial 是 (Mozilla 的) current favorite (but not the winner) ,我们也可以关注一下。说起来,Mercurial 的命令名很有趣,是 hg 。我花了几秒钟才反应过来,Hg 就是汞嘛 :D 。

下面再让我们看看几个候选人,Bazaar 的网站上有它和其它几种工具的比较。虽然有人说它性能不行,但我想那是针对 Mozllia 这种超级项目说的,我想对我们这样的小东西不会有什么影响。别的方面看起来很不错哟。尤其是它宣称的智能 rename ,真是太有爱了。

svn 下给目录 rename 绝对是场灾难。如果你不小心没有直接去仓库中 rename ,那么就意味着目录下所有文件的 del / add 。而即使你在仓库上直接操作,所有 client 都会大量的做 del / add 操作。每当这个时候,我都超心痛我的硬盘。

darcs 看起来也不错,我对 Haskell 本身就有莫名的好感,用 Haskell 写出来的软件对我就意味着稳定。虽然我自己不怎么玩 Haskell 也不太用 Python ,但是若让我花时间选一门语言玩的话,我会优先试试 Haskell 的。

作为 svn 的老用户,或许应该多关注一下 svk ,它在 svn 的基础上增加了一些分布式管理的东西。但是我不太喜欢这种补丁式的解决方案,因为设计总会随着需求而改变。若是背上太多历史包袱会让我有些不详的预感。

最后可以看看 GNU Arch 。我浏览了 arch 的 wiki 中 WhyArch 这一页,吸引我的是最后两条:

  1. Arch is lightweight

  2. Arch has a clean and transparent design

不过从 google 搜索结果来看,我没觉得 GNU Arch 是个有前途的项目(相比前面几个而言)。


对于我这样依然有部分时间在 Windows 环境下苟延残喘的程序员来说,有个好消息。那就是托开源的福,可爱的小乌龟无处不在。

  1. Mercurial 的乌龟版:TortoiseHg

  2. Bazaar 的乌龟版: TortoiseBZR

  3. Darcs 的乌龟版: TortoiseDarcs

不过就我的历史经验,只有 TortoiseSVN 是正宗乌龟,最好用。不用对其它版本乌龟的操作手感抱太大希望。


1 月 23 日 补充:

下面很多朋友谈到,合理的使用 branch 的功能就能解决我碰到的大多数问题。

没错,的确是这样。但是我们现在使用的 svn ,由于各种原因开 branch 都是件很麻烦的事。并不是指操作麻烦,而是管理麻烦。我们没有专门的代码仓库管理人员,大家比较松散。另外,在经过一次安全事故后,公司要求严格控制代码树上每个分支的读写权限。最终导致开 branch 成本过高,而很少有人日常使用。

前面提到分布式版本控制工具提供了方便的仓库合并功能,这个仓库合并其实就是分支合并。并非 svn 没有,而是做的不方便。这一点正如 cvs 的一个老问题:如何方便的确定一组文件的版本,我们可以用 tag 来解决,但终究不如 svn 那样每次多文件提交都是单一原子操作来的方便。

Comments

现在分布式版本管理工具貌似是git的天下了
空间占用太大。
通俗易懂 ,好文
程序员世家啊,现在可以重新考虑git了,我就是搜git搜到这来的...
我正在考慮從 svn 跳到 mercurial, 看到你的文章... 對了,版主提到的U盤問題,一般可以用底下svn switch 解決: svn switch --relcoate file:///X:/svn_server file:///Y:/svn_server X 是先前的drive,Y是現在的 drive.
有趣的是,从什么的旧模式,它可以适用?
上面提到的SVN的cache的问题,我想可以通过乌龟的设置去缓解! 情景:开发人员从SVN的仓库中checkout后带回家修改,家里没有网络无法提交,他怎么去实现这个过程的版本控制? 各位有没有比较简单可靠的方法实现,我用TortoiseSVN,期待您的回复(ouchaoguang1982@163.com)!谢谢!
找到博主的这篇文章,我最近也考虑从svk转到mercurial上来。有个疑问:你这里说mercurial支持智能rename,比svn强很多。可是我看到的资料是mercurial并不支持智能rename,bazaar才支持的。
U盤可以改盤符的
这问题还是挺麻烦的。 我是这么解决的: 开发的时候 在本机上建立一个版本仓库。 要向 googlecode.com 提交的时候再 switch过去 不过这样有时候会有一些问题。 只好吧 .svn 去掉 checkout
我用P4,感觉非常的不错,不过就是有个一个弊端.free版本只是支持2个client computer. 我们公司的是美国服务.从那边架构,结合了test.挺好用. 还有bug-reporting,issue-site.等等.只是配置起来极其麻烦. 不过配置好了.每天download,coding,checkin,get debug reporting email... 很是轻松. 支持多人并行开发.代码只能合并... 有这样功能的版本控制.不知道还有那些呢.知道的大大请tell me. 3q.
我在以前的公司用过两年ClearCase+ClearQuest,现在换到svn我只觉得神清气爽,ClearCase首先购买成本就太高,对配置管理人员要求也太高,稍有不慎就会出大问题,另外太过重量很不灵活,更重要是就算用了CC+CQ你还是需要在相关的管理条款上加很多限制,其中很多本可以通过软件来进行硬性限制。这整个会导致公司研发这部分的管理成本急剧狂升。换SVN之后清爽多了。 目前我们也是对GIT很有兴趣,只不过工作环境还是Win32所以还处在观望状态。但无论无何是再也不可能用回CC+CQ。
Git的win32版本可以看看这里http://code.google.com/p/msysgit/
不用分支?那简直等于没用配置管理。
我觉得ClearCase 搭配 ClearQueqst 不错.
vss 的多重锁我没用过,但是很多人都跟我提过。其实各种 SCM 工具只要合理使用,总能满足我们的需要,只是由于设计理念的不同,使用上有偏重。vss 就是偏重锁机制的。而 svn 也可以对文件上锁,只是用的人比较少。 好的工具应该是让用户用最自然的方法从最简洁的途径满足用户的需求。当我们需求大多数依赖简单的锁机制,大家都集中开发的时候,vss 自然是很不错的。 ps. 我认为使用文件系统不是错,svn 现在还推荐用本地文件系统而不要用 BDB 呢。 vss 一个较大的问题是,当开发人员不在一个局域网上时,他配置起来很麻烦,访问效率也比较低。
也许你不知道吧, VSS有多重加锁的功能, 就是一个文件可以上多把锁, 然后提交时弹出合并用户界面. 这一点我还是很怀念VSS的. VSS被人诟病的应该是不够稳定,以及采用文件系统来存储. VSS整个分支的merge也是相当棒的(我在2001年以前一直用VSS)
推荐Mercurial 我一直在用,感觉还行 连netbeans官方都用Mercurial了,还做了一个不错的netbeans插件 或者用cygwin跑git也行 你提的情况都很典型,很明显是应该用分布式版本控制 但是,我一直觉得分布式版本控制有一个很大的缺点,就是权限和认证部分 有一则更新写着A做的,但你根本没有办法确定是不是B冒充的 因此也只能在可信任的情况下使用
svn 可以 make patch, 做到类似 Archive 的功能。 用乌龟版可以很方便的 make patch 和 apply patch 。 其实,上面提到的问题都不是不能解决,只是麻烦而已。
怎么不谈女朋友?
我说一下我们的解决方案,我这用的企业套装软件是 Siebel,它自带版本控制功能。 和VSS,CVS相比(SVN没用过)特点是这样的: 1.本地可以lock,然后改代码,但是这样就不能check in,一旦check out将意味着本地的文件全部被仓库里的文件替换掉。不允许多人check out,这一点和vss一致。 2.Archive和import功能,可以把本地的所有的东西打成一个包。所以,我们可以在本地改好以后,再做check out,然后把Archive出来的包,import到本地,导入的过程中出现不一致的地方,可以选择overwrite,merge,no import。Merge可以选择要包里的东西,或者不要,要则意味着放弃本地文件里的东西,最小单位是一个function。 问题1:我想,大家都会想到把一个阶段的代码复制粘贴到一个Text文件保存着。而我是在本地有大量archive出来的包,以打包时间来命名。 问题2:甲做check out,乙把自己代码写到一个function,然后Archive给甲,甲做Merge的时候保留乙的function,其余全部不要。 问题3:Archive出来,到了公司再做check out,import。 问题4:还是Archive。 不知道哪个版本控制工具也有类似的功能。
一直都用的CVS,感觉挺好用啊,关键是每个人都要有版本管理的意识
以前一直用cvs,刚转到svn,目前还没有感受需要仓库合并的功能。也许问题在后期会慢慢显现出来吧。
没有人用Perforce吗
目前公司的项目都是使用VSS,1-4点问题经常遇到也只能叹气,不过用SVN的话可以通过branch来解决,而TAGS更可以用来标志已发布版本,相比VSS来说强大得多了
最好的版本控制应该是ClearCase,如果不考虑价格因素和专职CM的开销的话 甚至我觉得再开发一个便宜的替代产品都会是一个好的生意
嗯,svn占用得本地空间实在太大了
这篇文章写的很好也很有趣。感觉云风的技术文章写得越来越成熟了
由于管理上的原因, 我们并不是每个人都有权限可以随时随地的开 branch . 同样因为安全原因, 我们在一次安全事故后取消了所有个人的 vpn 登陆。
VC用tortoiseSVN,Java用CVS(eclipse中集成),主要用于个人开发的版本管理,尤其是做了一坨的修改以后如果感觉不当能回滚,还有一些分支版本、里程碑版本的标记,其他功能不是很关心
Mercurial 也有水星的意思哦 ;-)
非常不喜欢SVN,自从公司迁移到SVN上后我经常抓狂(之前用的是MKS SI,然后配合自己写的脚本),SVN的本地Cache实在是……,慢,容易出错,万一Screw up之后很难恢复,占用非常多的空间,而TortoiseSVN的Cache非常占内存,然后脱慢机器。 你说的几个问题,对于比较大的模块,单独开一个branch提交,然后做完之后merge到trunk上吧,编译通过不了不会break trunk就可以了。两个人合作也用这个办法吧,共用一个branch。在家的话,vpn连进公司允许么?
没有完美的版本控制方案啊 最近刚看了下AlienBrain,给美术用的,程序没必要

Post a comment

非这个主题相关的留言请到:留言本