Git vs Svn 谁更好?

起因

昨天同事过来问我,git一般是如何提交代码的。我吧啦吧啦说了一堆,同事一句,好像和svn差不多呀。我瞬间失语,我说我感觉git比svn好,同事问我,哪里比svn好?我说不出来。同事说等我想出来再和他说好了,我说好的。

随即,我就谷歌「git vs svn」,看看网上别人如何说的。在stackoverfiow上找到一个答案,说的很好,特来翻译给大家看看。

正文

git不比svn更好,但也不差,它们只是不同的。
他们最关键的区别在于,git是自治的,或者叫权利下放的。想象你是一个在外出路上的开发者,你在自己的笔记本电脑上开发,你希望能够对源码进行控制,以便将代码回退到3小时以前的状态。

如果你使用的是Subversion,那么你将会遇到一个问题:SVN 的代码仓库可能处于一个你暂时无法访问的地方(比如在公司内网,或者你没有网路),所以你无法提交。如果你想对当前代码产生一个副本或者拷贝,那么你只好手动去复制/粘贴。

如果你使用的是Git,你将不会遇到这个问题。你的本地拷贝就是一个仓库,你可以提交代码,并因为拥有代码的控制而获益。当你重新连接上主仓库,你就可以进行commit了。

这让人感觉非常好,不过这是在增加其(git)的复杂度而实现的。

Git看起来非常新、闪耀、酷的东西,我没有对它有不好的意思(毕竟,Linus为了Linux 内核的开发而开发了它),只是我感觉很多人去学习”分布式版本管理控制”仅仅因为它是新的,并且是Linus Torvalds开发的,而并不知道为什么或者是否git更好。

Subversion确实有它的问题,但是这些问题同样也存在于Git, Mercurial, CVS, TFS或者其他什么。

编辑:这个答案是我一年前写的,并且现在依然在获得赞同票,所以我想我应该增加一些解释。自从去年我写了这篇答案,Git获得了很多契机和支持,特别是像GitHub这样的网站发展非常快。现在我同时使用svngit,我想分享一些个人的看法。

首先,git真的会把刚刚接触这种自治的版本管理控制系统的人弄糊涂。什么是remote,如何正确的初始化仓库?这是两个刚刚接触git的人弄糊涂的问题,特别是相比于svn这种简单的由主服务器创建的方式。Gitgit init命令可以跟随两个参数bare,share,到底哪个才是正确的建立一个集权式的仓库。git确实有哪些好处,但它增加复杂度。在git文档,关于checkout命令是非常容易弄糊涂刚刚切换到git的开发者。’正确’的方式似乎是git clone,而git checkout是用来切换分支的。

Git确实非常流弊,当你适应了它的这种权利下放方式。我在家里部署了一个服务器,并在路上使用笔记本进行开发,这时,svn就不能很好的工作了。当使用svn的时候,当我没法连接远程仓库的时候,我就没法对源码进行一系列的控制(是的,我知道svk或者其他方式可以复制仓库)。对于git而言,这种无法连接服务器的方式,是默认的。它有其他的方式来做到和服务器连接(git的提交是本地的,它通过git push origin master的方式,将本地的master分支推送到叫origin的远程服务器)。

正如上面所说的,git增加了复杂度,两种创建仓库的方式,checkoutclonecommitvspush。你必须知道哪个命令是在本地工作,而哪个是对应服务器(我假定大部分人还是喜欢中心主仓库模式的)。

当然,git的工具仍然有它的不足,至少在window平台上是这样。是的,它有Visual Studio的插件,但是我还是使用msysgitgit bash

svn有它的优势,它足够简单易学:这是你的仓库,所有的改动都指向它,只要你知道cratecommitcheckout,你就可以开始工作了,你就知道如何切换一个分支,更新代码这样的内容。

git的优势在于,它非常适合那些无法随时随地的连接服务器的开发者。当然,它也比svn快很多。根据我听说的,git对于分支和合并的支持好于svn非常多。正如它被寄予期望的,这也是正是它被创造出来的主要原因(linux对于合并和分支有极高的要求,因为linux的开发者来自全球各地,它们需要并行开发,然后再合并到一起)。

这也解释了为什么git在网络上获得很多支持的原因,因为Git非常使用与开源项目:只要fork仓库,在自己的fork中提交改动,然后向原始项目的维护者去提交你的改动。有了Git,一切都OK。没错,在github上试试吧,太神奇了。

我同样见到Git-Svn Bridges:中心仓库是svn的,只是开发者在本地使用git,然后通过这个桥将代码提交到svn

即使增加了这么多的说明,我还是保持我的观点:Git并不比Svn更好或者更差,它们仅仅是不同而已。如果你需要离线的源码控制,并且愿意去花时间学习它,那么它是极好的!但是,如果你有一个严格的中心代码仓库,并且因为你的同事们都对它不感兴趣,而导致你很难引入svn,那么一个简单并且非常好用的(至少在window上)的svn工具将是你最好的选择。

个人见解

对于decentralized的中文解释,我想多说几句。这个词的意思是权利下放,git的实质是,每个本地仓库,都是一个完整的仓库,如果你的仓库是最新的版本,那么你可以看到所有人的每一次提交,以及提交的所有内容,这些都可以在不连接网络的情况下做到。这就是分布式版本管理控制系统。没有一个明确的中心,每一个人都可以是中心,一旦有一个中心坏了,一点都不用为此担心,因为它分身无数。而每一个分身都是一个完整的它。

是的,这听起来更像是不死的恶魔(笑)。

正因为若此,所以每个人都可以在本地对代码进行任何处置。将代码合并到服务器的行为只是将所有人的操作合并起来而已,就像每个人的操作都是一个点,每个人都自己产生几个点,这所有的点都在同一个时间轴上,时间轴可以想象成一条线,而合并就是将所有点合并在同一条线上。

也正因为所有的本地代码都是完整的,所以合并的行为是在本地进行的。想要合并代码,首先需要将最新的服务器代码拉到本地,然后,将本地中的远程服务器代码与本地代码进行合并(虽然都在本地,但一个远程服务器的代码,一个是本地修改的代码)。合并完成之后,你的代码就是最新的了,然后将你最新的代码推送到远程服务器上即可。

这里有个问题,git怎么知道你的代码此时是最新的呢?因为有时间轴(这里为了简化概念,实际上不是时间轴概念,只是在比较低级的层面可以这样理解)。

个人感觉

这位回答者说的很有道理,git的问题在于它不好学,有很多概念需要理解,有很多个纬度,本地的纬度,本地与远程服务器的纬度。

所以,我周围的朋友,在切换到git上,都非常的不适应,概念上太难转变,又没有显而易见的收益,所以不会主动去学习git

但是,就我个人来看,git在未来一定是趋势,这是大势所趋。很多人用git或者学习它,和git是不是linux的创建者来创造没有什么关系(至少在中国,Linus Torvalds并不是非常有名)。它更符合这个时代,它去中心化,每个人都是完整的。它可以利用零碎的时间,在飞机上都可以进行开发是一个很好的体验。它可以进行快速迭代,多分支并行开发。有些虽然svn也可以做到,但是相比git要差上一些。它对于提交代码的方式,也更加合理(pull requrest)。