版本管理 分布式的版本控制工具

laofo · 2010年03月15日 · 9 次阅读

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

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

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

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

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

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

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

某人写了一个模块,总是有 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 这一页,吸引我的是最后两条:

Arch is lightweight

Arch has a clean and transparent design

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

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

Mercurial 的乌龟版:TortoiseHg

Bazaar 的乌龟版: TortoiseBZR

Darcs 的乌龟版: TortoiseDarcs

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

1 月 23 日 补充:

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

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

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

http://blog.codingnow.com/2008/01/distributed_version_control.html

来自冰山一角 2009-12-13 15:03:37 查看原文 标签: 乱弹 experience linux mercurial scm 分布式

大多数人都知道或者善用多种版本管理系统,传统集中式版本管理系统有 CVS、SVN 等,后来,出现了一些分布式管理系统,如 GIT、mercurial 等。几乎所有有开发工作的公司,都会选择一个版本管理系统,并且制定一些规范来管理代码,道理很简单,使用版本管理系统能在多人开发,跟进 bug,追查问题方面减少很多管理和沟通的成本。

但是,我觉得个人的代码,包括一些软件配置文件,完全可以使用分布式版本管理系统来管理,可以让我们减轻很多麻烦。

使用传统的集中式版本控制软件来管理,好处如下:

不用担心因为无意的错误修改,删除而丢失过去的代码 可以随时查看历史情况,你就不用为 “xx 功能、yy 修改到底是什么时候加进来的,为什么要加” 这类事情而挠破头皮了 可以进行分支开发,比如说一个功能你不是很确定能否实现,拉一个分支开发就是了 更进一步,使用分布式的版本控制还有如下好处:

在本地就有版本仓库,你可以在任何时候进行 ci 和 roolback,无需联网 超级快速的分支切换 方便的和他人(其他机器)共享代码,一个 push,或者 pull,就能快速的同步修改 下面我举几个例子来让大家感受一下善用分布式版本管理的好处。

保证多台机器上的配置文件统一 我们有很多很多配置文件,尤其是 linux 下。vim 配置,apache 站点设置,桌面的配置,pidgin 的账号设置等等。 但是如果有多台计算机,如果两台机器上配置不统一,用起来不顺手,更可能会带来麻烦,我们需要找到这些配置文件,并且拷贝一份最新的到当前机器,但是如果两边都有修改,就可能会丢失修改,或者需要手动 merge。 过去可能用人使用过 rsync 来同步文件,能解决部分问题,但是如果使用分布式版本管理系统,在每台机器上都有一个独立的代码仓库,用这来管理配置文件再方便不过了!

首先,我们现在一台拥有最新版本配置文件的机器上初始化一个版本库

cd ~/ hg init hg add .vimrc .screenrc .fvwm # 添加所有你关注的配置文件 然后,一旦有新机器需要使用这个配置,clone 一份即可

cd ~/ hg clone ssh://berg@lastPC://home/berg/ hg up 如果在任何一台机器上有修改,只需要 ci 到当前机器,并且到其他机器上 pull 这份修改。

hg ci ssh berg@anotherPC://home/berg/ 我们不需要关心代码的合并,也不需要关心配置文件的具体名称和位置(在 linux 下面,所有的配置都是隐藏文件),一切细节都交给 mercurial 来管理。

使用中心服务器 分布式管理原则上是没有一个强制的中心服务器,但是如果我们在管理的规则中加上中心服务器,在某些时候就能避免一些尴尬的发生。

举一个例子,假设我有三个开发环境,一台在公司,一台在家里,还有一台服务器。在公司时,我家里的机器是离线的,在家里则反过来。于是我白天在公司开发完毕后,想在家里获得最新的版本,最简单的办法就是在服务器上架设一个中心版本库,下班时,push 代码到服务器上,回家就可以直接 pull 了。

使用中心服务器可以避免在需要开发时,发现最新版本所在计算机不在身边,并且处于离线状态的尴尬。

灵活的分支开发 不要以为分支功能在小项目中就毫无用处,有的时候,善用分支可以减少很多麻烦。而集中的版本控制系统处理分支很麻烦,让人避退三舍,可是到了分布式版本控制这里,分支变得很简单,看看下面的例子。

我在开发一个项目时,遇到了一个较大的修改,涉及面较广。 如果直接在主干上开发,如果在开发过程中发现了 bug,或者其他临时插入的想法,我有两种选择:

直接在线上修改,或者重新 clone 一份到本地的其他目录进行开发 把 “projectA” 这个项目做为一个分支在本地开发 两种好处的优劣是很明显的,第一种,我要么需要冒线上修改的风险,要么需要在本地配置另外一套环境;而第二种,我只需要在碰到其他问题的时候,将分支切换回去就好了。下面是命令示例:

首先,将本地仓库的当前 branch 设置成项目 A 的名称:projectA

hg branch projectA 我进行 projectA 分支的开发,如果在开发的过程中,我需要切换到原来的分支:

hg ci -m "projectA commit"

hg up default # 切换到主干 开发完毕后提交并且 push 到线上:

hg ci -m "modified something"

hg push 接下来我又能迅速的切换回原来开发到原来开发到一半的 uploadify 分支

hg up projectA 分布式版本管理的好处一下就体现出来了,我可以在本地迅速的切换分支,分支建立的成本也很低。这样能让我们更灵活的应对需求

小结 好了,本文就写到这里。小结一下,使用分布式版本管理系统管理个人 mini 项目、软件配置文件,能给开发和管理带来很大的便利,使用中心版本仓库能避免机器离线导致无法获取最新代码的问题,善用分支能让开发者更灵活的应对需求。

看了本文后,是否你对分布式管理系统也充满了兴趣呢?或者你有一些更好的实践?欢迎在下面留言共同探讨。 http://www.budoou.com/article/281826/

分步式工具听说是下一代的管理工作(听说:lol ),最近有空也在看一下分布工具的使用(如Git),希望多多交流,共同进步!

需要 登录 后方可回复。