Effective branching is the killer feature of git or any source control system, to me. And in that regard:
svn < mercurial < git
svn: Three way merges are close to impossible. When you do a three way merge of a file you need to find the common ancestor of all three versions. This is just an incredibly difficult problem in svn that to my knowledge can't be solved in a way thats durable. In mercurial and git you can simply walk the graph to the common ancestor.
mercurial: Somewhat fails at the concept of a short lived local branch. You can't create a local branch in place--without cloning the entire repository to a different folder--to try out some feature and then delete the branch if it doesn't work out. At least not without using bookmarks or extensions: mq, localbranch. With these you get a bookmark, a patch queue, or an in-repository clone, respectively. None of these are branches in the fundamental sense.
git: You can get a short lived local branch, a long lived one, a release branch, a bug fix branch, a feature branch, branch, branch, branch. In git branching just works, and that, to me, if compared to mercurial, means specifically working local branches that are not fundamentally different to the rest of the repository.
Branching & merging are also insanely easy to do, so I find that I develop almost all new features in their own branch, and I can easily just throw them away if I want, I never did this with subversion.
The kicker with Git is that all these branch operations take on the order of milliseconds because Git stores the entire project history -- all past revisions of files, etc -- locally. Sure, you pay in a bit of disk space, but consequently almost all common operations can be done without hitting the network and are crazy fast. Even when you execute a commit, you're not committing to a server, but to your working copy of the repository. Later, you can push your changes somewhere else and merge accordingly.
Obviously, if you add a 1GB random file then delete it, the git entire history will have 1GB more data than an SVN checkout. but usually, it's smaller.
I've switched to using gitsvn exclusively for svn projects I'm involved with since I noticed that -- I save space and have complete project history locally. What more could you ask for?
(p.s: git svn is a better svn client than svn. really)
Here's an example scenario I described in my blog an year back. http://tuxychandru.blogspot.com/2010/01/how-git-shines-above...
|
| file p.txt contains "X"
|
+<---(branch)--------+
| |
* file p.txt renamed |
| to f/p.txt, which |
| contains "X" |
| * the content of file p.txt is updated to
| | contain "Y"
| |
| |
+----(merge)-------->+ file p.txt is deleted and file f/p.txt is created
| with the content "X"
|
| BUT expected/wanted content is: "Y" (or at least a conflict)
V