They both work with the same
abstractions: a series of snapshots (changesets) which make up the history.
Each changeset knows where it came from (the parent changeset) and can have
many child changesets. The recent hg-git extension provides a two-way bridge
between Mercurial and Git and sort of shows this point.
Git has a strong focus on mutating
this history graph (with all the consequences that entails) whereas Mercurial
does not encourage history rewriting, but it’s easy to do anyway and the
consequences of doing so are exactly what you should expect them to be (that
is, if I modify a changeset you already have, your client will see it as new if
you pull from me). So Mercurial has a bias towards non-destructive commands.
As for light-weight branches, then
Mercurial has supported repositories with multiple branches since…, always I
think. Git repositories with multiple branches are exactly that: multiple
diverged strands of development in a single repository. Git then adds names to
these strands and allow you to query these names remotely. The Bookmarks
extension for Mercurial adds local names, and with Mercurial 1.6, you can move
these bookmarks around when you push/pull..
I use Linux, but apparently
TortoiseHg is faster and better than the Git equivalent on Windows (due to
better usage of the poor Windows filesystem). Both http://github.com and
http://bitbucket.org provide online hosting, the service at Bitbucket is great
and responsive (I haven’t tried github).
I chose Mercurial since it feels
clean and elegant — I was put off by the shell/Perl/Ruby scripts I got with
Git. Try taking a peek at the git-instaweb.sh file if you want to know what I
mean: it is a shell script which generates a Ruby script, which I think runs a
webserver. The shell script generates another shell script to launch the first
Ruby script. There is also a bit of Perl, for good measure.
I like the blog post that compares
Mercurial and Git with James Bond and MacGyver — Mercurial is somehow more
low-key than Git. It seems to me, that people using Mercurial are not so easily
impressed. This is reflected in how each system do what Linus described as
“the coolest merge EVER!”. In Git you can merge with an unrelated
repository by doing:
git-checkout-cache -a -u
git-update-cache –add —
cp .git/FETCH_HEAD .git/MERGE_HEAD
Those commands look quite arcane
to my eye. In Mercurial we do:
hg pull –force
Notice how the Mercurial commands
are plain and not special at all — the only unusual thing is the –force flag
to hg pull, which is needed since Mercurial will abort otherwise when you pull
from an unrelated repository. It is differences like this that makes Mercurial
seem more elegant to me.
Git is a platform, Mercurial is
“just” an application. Git is a versioned filesystem platform that happens to
ship with a DVCS app in the box, but as normal for platform apps, it is more
complex and has rougher edges than focused apps do. But this also means git’s
VCS is immensely flexible, and there is a huge depth of non-source-control
things you can do with git.
That is the essence of the
Git is best understood from the
ground up – from the repository format up. Scott Chacon’s Git Talk is an
excellent primer for this. If you try to use git without knowing what’s
happening under the hood, you’ll end up confused at some point (unless you
stick to only very basic functionality). This may sound stupid when all you
want is a DVCS for your daily programming routine, but the genius of git is
that the repository format is actually very simple and you can understand git’s
entire operation quite easily.
For some more
technicality-oriented comparisons, the best articles I have personally seen are
The Differences Between Mercurial
Reddit thread where
git-experienced Dustin answers his own git neophyte questions
He has actually used both DVCSs
extensively and understands them both well – and ended up preferring git.
There’s one huge difference
between git and mercurial; the way the represent each commit. git represents
commits as snapshots, while mercurial represents them as diffs.
What does this means in practice?
Well, many operations are faster in git, such as switching to another commit,
comparing commits, etc. Specially if these commits are far away.
revision control uses a peer-to-peer model rather than using a centralized
server to store code updates. While a peer-to-peer model would work better for
world-wide, open source projects, it may not be ideal in other situations. The
downside to a dedicated server approach is that when the server is down, no
clients are able to access the code.
(http://mercurial.selenic.com/) began close to the same time as Git and is also
a distributed revision control tool. It was originally made to compete with Git
for Linux kernel development, and as Git was selected, Mercurial has seen less
success in that area. However, that is not to say that it is not used as many
major developments use it, including OpenOffice.org. It’s different from other
revision control systems in that Mercurial is primarily implemented in Python
as opposed to C, but there are some instances where C is used. Due to its
distributed nature and its creation in Python, the Python language developers
are considering a switch to Mercurial as it would allow non-core developers to
have easier access to creating new trees and reverting changes.
Some of the major
drawbacks to Mercurial include that it doesn’t allow for two parents to be
merged and unlike Git, it uses an extension system rather than being
scriptable. That may be ideal for some programmers, but many find the power of
Git to be a feature they don’t want to trade off.