我已经使用Subversion很多年了,在使用SourceSafe之后,我爱上了Subversion。结合TortoiseSVN,我真的无法想象它还能有什么更好的。

然而,越来越多的开发人员声称Subversion存在问题,我们应该转向新的分布式版本控制系统,比如Git。

Git如何改进Subversion?


当前回答

“为什么Git比X好”概述了Git相对于其他scm的各种优缺点。

简要:

Git tracks content rather than files Branches are lightweight and merging is easy, and I mean really easy. It's distributed, basically every repository is a branch. It's much easier to develop concurrently and collaboratively than with Subversion, in my opinion. It also makes offline development possible. It doesn't impose any workflow, as seen on the above linked website, there are many workflows possible with Git. A Subversion-style workflow is easily mimicked. Git repositories are much smaller in file size than Subversion repositories. There's only one ".git" directory, as opposed to dozens of ".svn" repositories (note Subversion 1.7 and higher now uses a single directory like Git.) The staging area is awesome, it allows you to see the changes you will commit, commit partial changes and do various other stuff. Stashing is invaluable when you do "chaotic" development, or simply want to fix a bug while you're still working on something else (on a different branch). You can rewrite history, which is great for preparing patch sets and fixing your mistakes (before you publish the commits) … and a lot more.

有一些缺点:

There aren't many good GUIs for it yet. It's new and Subversion has been around for a lot longer, so this is natural as there are a few interfaces in development. Some good ones include TortoiseGit and GitHub for Mac. Partial checkouts/clones of repositories are not possible at the moment (I read that it's in development). However, there is submodule support. Git 1.7+ supports sparse checkouts. It might be harder to learn, even though I did not find this to be the case (about a year ago). Git has recently improved its interface and is quite user friendly.

在最简单的用法中,Subversion和Git是差不多的。两者之间没有太大区别:

svn checkout svn://foo.com/bar bar
cd bar
# edit
svn commit -m "foo"

and

git clone git@github.com:foo/bar.git
cd bar
# edit
git commit -a -m "foo"
git push

Git真正的亮点在于分支和与其他人一起工作。

其他回答

来自SourceGear的Eric Sink写了一系列关于分布式和非分布式版本控制系统之间区别的文章。他比较了最流行的版本控制系统的优缺点。非常有趣的读物。 文章可以在他的博客www.ericsink.com上找到:

阅读差异 Git是版本控制工具中的C Git缺乏对不变性和DVCS最佳实践的尊重 DVCS和dag,第1部分 DVCS和dag,第2部分 DVCS和Bug跟踪 合并历史,dag和Darcs Git为什么这么快? Mercurial, Subversion和Wesley Snipes

它是分布的。基准测试表明,它的速度要快得多(考虑到它的分布式性质,像diffs和log这样的操作都是本地的,所以在这种情况下,它当然要快得多),而且工作文件夹也更小(这仍然让我大吃一惊)。

当您使用subversion或任何其他客户端/服务器版本控制系统时,您实际上是通过签出版本在您的机器上创建工作副本。这代表了存储库外观的时间快照。通过更新更新工作副本,通过提交更新存储库。

使用分布式版本控制,您没有快照,而是拥有整个代码库。想要一个3个月大的版本吗?没问题,3个月前的版本还在你的电脑上。这不仅意味着速度更快,而且如果您与中央服务器断开连接,您仍然可以执行许多您习惯的操作。换句话说,您不仅拥有给定修订的快照,而且拥有整个代码库。

您可能认为Git会占用大量硬盘空间,但从我看到的几个基准测试来看,它实际上占用的空间更少。不要问我怎么做。我的意思是,它是由莱纳斯构建的,我猜他对文件系统略知一二。

这里所有的答案都是意料之中的,以程序员为中心,但是如果你的公司在源代码之外使用修订控制会发生什么呢?有很多文档不是源代码,它们受益于版本控制,应该与代码接近,而不是在另一个CMS中。大多数程序员都不是孤立地工作——我们作为团队的一部分为公司工作。

考虑到这一点,比较Subversion和git在客户端工具和培训方面的易用性。我看不出有哪一种分布式修订控制系统会更容易使用或向非程序员解释。我很乐意被证明是错误的,因为这样我就可以评估git,并希望它能够被那些需要版本控制的人(而不是程序员)接受。

即便如此,如果管理层问我为什么我们应该从集中式版本控制系统转向分布式版本控制系统,我也很难给出一个诚实的答案,因为我们不需要它。

Disclaimer: I became interested in Subversion early on (around v0.29) so obviously I'm biased, but the companies I've worked for since that time are benefiting from my enthusiasm because I've encouraged and supported its use. I suspect this is how it happens with most software companies. With so many programmers jumping on the git bandwagon, I wonder how many companies are going to miss out on the benefits of using version control outside of source code? Even if you have separate systems for different teams, you're missing out on some of the benefits, such as (unified) issue tracking integration, whilst increasing maintenance, hardware and training requirements.

David Richards关于Subversion / GIT的WANdisco博客

The emergence of GIT has brought with it a breed of DVCS fundamentalists – the ‘Gitterons’ – that think anything other than GIT is crap. The Gitterons seem to think software engineering happens on their own island and often forget that most organizations don’t employ senior software engineers exclusively. That’s ok but it’s not how the rest of the market thinks, and I am happy to prove it: GIT, at the last look had less than three per cent of the market while Subversion has in the region of five million users and about half of the overall market. The problem we saw was that the Gitterons were firing (cheap) shots at Subversion. Tweets like “Subversion is so [slow/crappy/restrictive/doesn't smell good/looks at me in a funny way] and now I have GIT and [everything works in my life/my wife got pregnant/I got a girlfriend after 30 years of trying/I won six times running on the blackjack table]. You get the picture.

其他的回答很好地解释了Git的核心特性(这些特性非常棒)。但是还有很多小方法可以让Git表现得更好,并帮助我的生活更加理智。以下是一些小细节:

Git has a 'clean' command. SVN desperately needs this command, considering how frequently it will dump extra files on your disk. Git has the 'bisect' command. It's nice. SVN creates .svn directories in every single folder (Git only creates one .git directory). Every script you write, and every grep you do, will need to be written to ignore these .svn directories. You also need an entire command ("svn export") just to get a sane copy of your files. In SVN, each file & folder can come from a different revision or branch. At first, it sounds nice to have this freedom. But what this actually means is that there is a million different ways for your local checkout to be completely screwed up. (for example, if "svn switch" fails halfway through, or if you enter a command wrong). And the worst part is: if you ever get into a situation where some of your files are coming from one place, and some of them from another, the "svn status" will tell you that everything is normal. You'll need to do "svn info" on each file/directory to discover how weird things are. If "git status" tells you that things are normal, then you can trust that things really are normal. You have to tell SVN whenever you move or delete something. Git will just figure it out. Ignore semantics are easier in Git. If you ignore a pattern (such as *.pyc), it will be ignored for all subdirectories. (But if you really want to ignore something for just one directory, you can). With SVN, it seems that there is no easy way to ignore a pattern across all subdirectories. Another item involving ignore files. Git makes it possible to have "private" ignore settings (using the file .git/info/exclude), which won't affect anyone else.