转载:http://whitesock.iteye.com/blog/918874
1 Overview
Git作为一种Distributed Version Control System,和传统的Contralized Version Control System(例如SVN,CVS)相比存在很多不同之处,以下笔者认为相对来说比较重要的区别。本文提到的SVN版本为1.5,Git版本为1.7.0。
2 Differences
2.1 Data Storage
在每次提交时,SVN都会累加global revision number,同时在Data Store中存储revision间的差异部分;跟SVN相比,Git在提交时会对repository做一个完整的snapshot(一个commit对象,多个tree对象和多个blob对象),并且用一个SHA-1散列值来唯一标识该提交。这也许是Git和SVN最显著的区别之一,因为它影响到了Git很多特性的功能和实现方式。
默认情况下, svn checkout会创建repository HEAD的一个本地拷贝;git checkout则通常用来切换/创建分支。此外HEAD在SVN和Git中的含义也完全不同:在SVN中HEAD指向最新的revision;在Git中HEAD指向当前的branch。
在Git中与svn checkout对应的命令是git clone。跟svn checkout不同的是,git clone会创建repository的一个近乎完整的拷贝(Git 不支持SVN 的Sparse Directory特性),该拷贝与原始的repository之间也不是client/server的关系,而是完全平等的关系。
2.2 Moving Files
正如SVN取代CVS的多个原因之一,CVS无文件移动的概念,其后果就是对重构非常不友好。
SVN记录文件移动的历史。SVN中的peg revision(区别于operative revision)用于唯一确定一个versioned object。
Git并不跟踪文件的移动。如果你重命名了一个文件,Git并不保存跟移动相关的信息,但是Git可以隐式推测出文件移动。需要注意的是,Git虽然提供了git mv,但是它只是git rm和git add的便捷写法而已。
2.3 File Status Cycle
SVN和Git的working copy中的每个文件,都只能是tracked和untracked两种状态之一。但是跟SVN相比,Git增加了staging area的概念。Staging area虽然在某种程度上增加了Git使用的复杂性(例如git diff默认只是指比对working copy和staging area,git diff --staged/--cached显示staging area中即将提交的变更),但是也提供了更多的灵活性(例如git stash)。
2.4 Offline Operations
CVS基本上不支持离线操作,例如当你希望查看对working copy的修改时,只能使用cvs update,而cvs update依赖remote repository可以访问。
SVN支持有限的离线操作,这要归功于无处不在的.svn目录中保存的BASE版本。例如通过svn status即可查看对working copy的修改而无须访问remote repository(当然svn status -u例外)。支持离线操作的命令还有svn diff,svn revert。但是,svn list,svn update,svn commit和svn checkout等命令仍然是需要访问remote repository。
作为一种DVCS,Git支持丰富的离线操作。例如git update、git commit和git merge等命令都支持离线操作。Git中管理remote repository的命令有git remote、git fetch、git pull和git push等。但在能用好这些remoting相关命令之前,首先要充分理解tracking branches的含义,以及git remote show <name> 的用途。
2.5 Undoing Things
SVN中每一次提交的revision都是immutable的,因此SVN对于undo提供有有限的支持。例如在SVN中修改commit message就要颇费周折(需要调整pre-revprop-change hook或者使用svnadmin setlog --bypass-hooks)。
Git对undo提供了丰富的支持,例如通过interactive rebase,可以调整、合并、分割任意的commit 对象,通过branch-filter可以在每一次commit中删除文件等。
2.6 Locking
SVN支持显式的mutual exclusive lock。Git不支持。需要注意的是,在SVN中并不只是持有锁的用户可以解锁,实际上任何用户都可以解锁(通常称之为breaking and stealing locks)。
2.7 Branching and Merging
严格来讲,SVN不区分tag和branch。在创建tag或者branch时,SVN采用所谓的“cheap copy”(实际上每个revision都是之前revision的cheap copy)。
Git branching被称为killing feature,因此Git倡导使用branch。在创建一个branch时,Git只需要保存一个指向当前commit对象的pointer即可。
SVN支持mixed working copy,即working copy的不同目录中包含同一repository的不同分支的内容。在Git中貌似没有类似特性。需要注意的是,如果working copy中有未提交的修改,那么Git不允许切换分支(如果需要保留这些修改,那么应该使用git stash);而svn switch会尝试保留这些修改,并将切换后分支的内容和未提交的修改进行合并。
3 Reference
Pro Git, Scott Chacon
Version Control with Subversion, Ben Collins-Sussman, Brian W.Fitzpartrik, C.Michael Pilato