What is the Difference Between Mercurial and Git?
Asked Answered
T

25

726

I've been using git for some time now on Windows (with msysGit) and I like the idea of distributed source control. Just recently I've been looking at Mercurial (hg) and it looks interesting. However, I can't wrap my head around the differences between hg and git.

Has anyone made a side-by-side comparison between git and hg? I'm interested to know what differs hg and git without having to jump into a fanboy discussion.

Thaddeus answered 30/8, 2008 at 9:48 Comment(0)
A
345

These articles may help:

Edit: Comparing Git and Mercurial to celebrities seems to be a trend. Here's one more:

Afrikander answered 30/8, 2008 at 9:48 Comment(1)
"Git vs Mercurial Please Relax" is seriously out of date, although it's as old as this question. Maybe this question should be deleted and re-opened now that both tools have had 3+ years of features added.Biyearly
B
237

I work on Mercurial, but fundamentally I believe both systems are equivalent. 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 fetch <project-to-union-merge>
GIT_INDEX_FILE=.git/tmp-index git-read-tree FETCH_HEAD
GIT_INDEX_FILE=.git/tmp-index git-checkout-cache -a -u
git-update-cache --add -- (GIT_INDEX_FILE=.git/tmp-index git-ls-files)
cp .git/FETCH_HEAD .git/MERGE_HEAD
git commit

Those commands look quite arcane to my eye. In Mercurial we do:

hg pull --force <project-to-union-merge>
hg merge
hg commit

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.

Boschbok answered 30/8, 2008 at 9:48 Comment(7)
Note that TortoiseHg also works together with Nautilus, the Gnome file manager on Linux.Beadle
I use Mercurial much more than git, but in my experience github has always been faster and more responsive than bitbucket unfortunately...Aimo
The Ruby script is only generated if it the httpd is Webrick, the ruby webserver.Bennir
I can't speak for Mercurial, but git stores snapshots, not changesets. Patches are derived from adjacent snapshots when needed. This is an important conceptual difference when doing anything other than adding commits. It also has implications for tracking renames, for example (they can only be heuristically detected).Phyl
Like Git, Mercurial stores snapshots of your files when you commit. I do not agree that renames can only be tracked with a heuristic like in Git, there is nothing in the model that precludes adding extra information to a snapshot, e.g., rename information. We do that in Mercurial.Boschbok
to merge (pull) an unrelated project with git, you can simply do: git pull <url-of-project>. the mail you quoted is from the very early days of git (2005)Partition
knittl: ah, good, I'm glad to hear that Git is getting less arcane. Still, I think the example shows a bit how the systems differ in what we think it cool and Git feels more low-level to me compared with Mercurial (but not any more powerful).Boschbok
D
73

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 difference.

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 Dustin Sallings’:

He has actually used both DVCSs extensively and understands them both well – and ended up preferring git.

Demerol answered 30/8, 2008 at 9:48 Comment(3)
I've often read people mention git being a "platform", but that's more of a theory or common myth because there no major examples of it as a platform to do something other than run git.Disappointment
@Ian - If I am not mistaken Aptana Studio 3 uses it for its internal update system.Pharos
So, in a nutshell: Mercurial is an open-source distributed revision control system, and git is a lifestyle choice.Pokeberry
J
51

The big difference is on Windows. Mercurial is supported natively, Git isn't. You can get very similar hosting to github.com with bitbucket.org (actually even better as you get a free private repository). I was using msysGit for a while but moved to Mercurial and been very happy with it.

Justus answered 30/8, 2008 at 9:48 Comment(4)
So "natively" is not quite the right word, but it is not well supported under windows, that is for sure.Disappointment
git is supported to a point on Windows. But try using Unicode filenames cross-platform and see what pain you get.Nevers
@Craig: That's more of a platform shortcoming. A competent platform would allow you to switch to a suitable locale. If you stick to utf-8, you'll be mostly fine except that Mac OS X has slightly different normalisation of utf-8, however, I'm not sure if windows even lets you use utf-8...Sixfold
Windows supports Unicode, though MS chose to go for UTF-16 in its API rather than UTF-8. Despite that, it would be quite possible for git to support Unicode cross-platform. SVN has solved that problem quite well. But it's just not a high priority for the msysGit development at the moment. code.google.com/p/msysgit/issues/detail?id=80Nevers
J
38

If you are a Windows developer looking for basic disconnected revision control, go with Hg. I found Git to be incomprehensible while Hg was simple and well integrated with the Windows shell. I downloaded Hg and followed this tutorial (hginit.com) - ten minutes later I had a local repo and was back to work on my project.

Jevon answered 30/8, 2008 at 9:48 Comment(1)
I followed the same tutorial. It's definitive.Solidify
C
22

I think the best description about "Mercurial vs. Git" is:

"Git is Wesley Snipes. Mercurial is Denzel Washington"

Chafe answered 30/8, 2008 at 9:48 Comment(1)
How ist that supposed to help? Does that mean that git is more the martial arts type?Loris
M
20

They are almost identical. The most important difference, from my point of view (I mean, the reason that got me to choose one DVCS over the other) is how the two programs manage branches.

To start a new branch, with Mercurial, you simply clone the repository to another directory and start developing. Then, you pull and merge. With git, you have to explicitly give a name to the new topic branch you want to use, then you start coding using the same directory.

In short, each branch in Mercurial needs its own directory; in git you usually work in on single directory. Switching branches in Mercurial means changing directories; in git, it means asking git to change the directory's content with git checkout.

I'm honest: I don't know if it's possible to do the same with Mercurial, but since I usually work on web projects, using always the same directory with git seems much confortable to me, since I don't have to re-configure Apache and restart it and I don't mess my filesystem everytime I branch.

Edit: As Deestan noted, Hg has named branches, which can be stored in a single repository and allow the developer to switch branches within the same working copy. git branches are not exactly the same as Mercurial named branches, anyway: they are permanent and not throw away branches, like in git. That means that if you use a named branch for experimental tasks even if you decide to never merge it it will be stored in the repository. That's the reason why Hg encourages to use clones for experimental, short-running tasks and named branches for long-running tasks, like for release branches.

The reason why a lot of Hg users prefere clones over named branch is much more social or cultural than technical. For example, with last versions of Hg, it's even possible to close a named branch and recursively remove metadata from changesets.

On the other side, git invites to use "named branches" which are not permanent and are not stored as metadata on each changeset.

From my personal point of view, then, git's model is deeply linked to the concept of named branches and switch between a branch and another withing the same directory; hg can do the same with named branches, but yet it encourages the use of clones, which I personally don't like too much.

Michel answered 30/8, 2008 at 9:48 Comment(4)
This is not a difference; Hg has named branches too. We use them all the time during normal development instead of clone-branches.Mint
AFAIK, named branch in Hg are obtained storing metadata in each commit; I may be wrong, but I read that once you create a branch, its metadata will be embedded in each changeset and become part of the history. This is a huge difference with git. "Clones are great for quick experiments where you don't want to record a branch name, and named branches are good for long term branches" tinyurl.com/2wz39qx What I was trying to say with my post is that git's standard workflow invites you to use a single working copy; Hg standard workflow includes clones, which don't suite my personal needs.Michel
For a good explanation of similarities/differences re: branching in Git & Hg, see: mercurial.selenic.com/wiki/GitConcepts#Branch_modelLaflamme
named branches in hg are nothing like branches in git. In hg, there is one true path. All branches are branches off that path. In git there is no one true path. There's just different states of the repo and pointers into that state. Each branch is just a different pointer. Which pointer is the main one is up to use. Branches are all peers.Biyearly
N
18

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.

AFAIK there's no advantage of mercurial's approach.

Nicolanicolai answered 30/8, 2008 at 9:48 Comment(7)
Changesets (diffs) advantage is in taking up less space. Git recovers the space used for commits by using compression, but this requires an occasional explicit recompress step ("git pack").Townscape
It is now called 'git gc', but there are different levels of garbage collection, and some levels are executed automatically in recent versions of git.Nicolanicolai
+1. Yes, that's the main difference, I think (from the technical side).Foothill
actually mercurial uses snapshots as wellTorquemada
I fail to understand the distinction you're drawing between 'snapshots' and 'diffs'. Both hg and git store commits as (groups of) file deltas. Those deltas are based on whatever previous revision the respective SCM chooses. Have you got numbers that show that git is actually faster for the operations you mentioned? Updating to another commit spends most of its time writing to the working dir, not reading the repo, anyway.Fulminant
'Snapshot's vs. 'diff's - utterly irrelevant. However the repo is stored internally has no bearing on what the user sees. Both git and mercurial present the user with 'snapshot's. There's no reason why a repository format implemented in the same way as git couldn't be added to mercurial, just as I believe Bazaar did.Lindseylindsley
+Kevin No, git stores snapshots, not deltas, deltas are calculated by comparing two snapshots. +Mark It's true that nowadays that doesn't make much of a difference to the user (because both systems have implemented shortcuts), but it's still a technical difference.Nicolanicolai
B
11

If I understand them correctly (and I'm far from an expert on each) they fundamentally each have a different philosophy. I first used mercurial for 9 months. Now I've used git for 6.

hg is version control software. It's main goal is to track versions of a piece of software.

git is a time based file system. It's goal is to add another dimension to a file system. Most have files and folders, git adds time. That it happens to work awesome as a VCS is a byproduct of its design.

In hg, there's a history of the entire project it's always trying to maintain. By default I believe hg wants all changes to all objects by all users when pushing and pulling.

In git there's just a pool of objects and these tracking files (branches/heads) that determine which set of those objects represent the tree of files in a particular state. When pushing or pulling git only sends the objects needed for the the particular branches you are pushing or pulling, which is a small subset of all objects.

As far as git is concerned there is no "1 project". You could have 50 projects all in the same repo and git wouldn't care. Each one could be managed separately in the same repo and live fine.

Hg's concept of branches is branches off the main project or branches off branches etc. Git has no such concept. A branch in git is just a state of the tree, everything is a branch in git. Which branch is official, current, or newest has no meaning in git.

I don't know if that made any sense. If I could draw pictures hg might look like this where each commit is a o

             o---o---o
            /        
o---o---o---o---o---o---o---o
         \         /
          o---o---o

A tree with a single root and branches coming off of it. While git can do that and often people use it that way that's not enforced. A git picture, if there is such a thing, could easily look like this

o---o---o---o---o

o---o---o---o
         \
          o---o

o---o---o---o

In fact in some ways it doesn't even make sense to show branches in git.

One thing that is very confusing for the discussion, git and mercurial both have something called a "branch" but they are not remotely the same things. A branch in mercurial comes about when there are conflicts between different repos. A branch in git is apparently similar to a clone in hg. But a clone, while it might give similar behavior is most definitely not the same. Consider me trying these in git vs hg using the chromium repo which is rather large.

$ time git checkout -b some-new-branch
Switched to new branch 'some-new-branch'

real   0m1.759s
user   0m1.596s
sys    0m0.144s

And now in hg using clone

$ time hg clone project/ some-clone/

updating to branch default
29387 files updated, 0 files merged, 0 files removed, 0 files unresolved.
real   0m58.196s
user   0m19.901s
sys    0m8.957

Both of those are hot runs. Ie, I ran them twice and this is the second run. hg clone is the actually the same as git-new-workdir. Both of those make an entirely new working dir almost as though you had typed cp -r project project-clone. That's not the same as making a new branch in git. It's far more heavy weight. If there is true equivalent of git's branching in hg I don't know what it is.

I understand at some level hg and git might be able to do similar things. If so then there is a still a huge difference in the workflow they lead you to. In git, the typical workflow is to create a branch for every feature.

git checkout master
git checkout -b add-2nd-joypad-support
git checkout master
git checkout -b fix-game-save-bug
git checkout master
git checkout -b add-a-star-support

That just created 3 branches, each based off a branch called master. (I'm sure there's some way in git to make those 1 line each instead of 2)

Now to work on one I just do

git checkout fix-game-save-bug

and start working. Commit things, etc. Switching between branches even in a project as big as chrome is nearly instantaneous. I actually don't know how to do that in hg. It's not part of any tutorials I've read.

One other big difference. Git's stage.

Git has this idea of a stage. You can think of it as a hidden folder. When you commit you only commit what's on the stage, not the changes in your working tree. That might sound strange. If you want to commit all the changes in your working tree you'd do git commit -a which adds all the modified files to the stage and then commits them.

What's the point of the stage then? You can easily separate your commits. Imagine you edited joypad.cpp and gamesave.cpp and you want to commit them separately

git add joypad.cpp  // copies to stage
git commit -m "added 2nd joypad support"
git add gamesave.cpp  // copies to stage
git commit -m "fixed game save bug"

Git even has commands to decide which particular lines in the same file you want to copy to the stage so you can split up those commits separately as well. Why would you want to do that? Because as separate commits others can pull only the ones they want or if there was an issue they can revert just the commit that had the issue.

Biyearly answered 30/8, 2008 at 9:48 Comment(3)
"Git even has commands to decide which particular lines in the same file you want to copy to the stage so you can split up those commits separately as well." What are these commands?Inferential
@James: git add --patch, see linux.die.net/man/1/git-add or use git add -i, like in stackoverflow.com/questions/2372583/…Redcoat
@gman: instead of checking out the master and branching with checkout -b <name> you could just use git branch <name> to create a new branch without switching to itRedcoat
I
11

Also google's comparison (though it's a bit old, done in 2008)

http://code.google.com/p/support/wiki/DVCSAnalysis

Ionian answered 30/8, 2008 at 9:48 Comment(0)
S
11

Nothing. They both do the same, both perform about equally. The only reason you should choose one over the other is if you help out with a project that already uses one..

The other possible reason for choosing one is an application or service which only supports one of the system.. For example, I pretty much chose to learn git because of github..

Stylet answered 30/8, 2008 at 9:48 Comment(1)
Looks like your answer was far too pragmatic. :)Sixfold
T
8

There is a dynamic comparison chart over at the versioncontrolblog where you can compare several different version control systems.

Here is a comparison table between git, hg and bzr.

Thaddeus answered 30/8, 2008 at 9:48 Comment(2)
The information on Mercurial is not entirely accurate: Mercurial do have "intelligent merges after moves or renames". Concretely, this means that if I rename dir-a/foo.c to dir-b/foo.c and keep working on dir-b/foo.c, then your work on dir-a/foo.c will be correctly merged with my work after a pull.Boschbok
The information (it comes from Better SCM Initiative comparison, IIRC) about Git is also inaccurate or even inavlid in a few places.Spitler
L
7

One thing to notice between mercurial of bitbucket.org and git of github is, mercurial can have as many private repositories as you want, but github you have to upgrade to a paid account. So, that's why I go for bitbucket which uses mercurial.

Lowbred answered 30/8, 2008 at 9:48 Comment(0)
F
7

Are there any Windows-based collaborators on your project?

Because if there are, the Git-for-Windows GUI seems awkward, difficult, unfriendly.

Mercurial-on-Windows, by contrast, is a no-brainer.

Firmament answered 30/8, 2008 at 9:48 Comment(2)
I like git, but I have to agree here. Git has a nicer command line with the stage and better documentation. I would happily use the git commands with a posix shell. However tortoiseHG on windows is great, it even integrates with several diff tools (beyond compare) and has full support for sub-repos, and many hg plugins like strip/mqPsychasthenia
There is at least one very good Windows (and OS X + Linux) Git GUI available.Delay
H
7

There are quite significant differences when it comes to working with branches (especially short-term ones).

It is explained in this article (BranchingExplained) which compares Mercurial with Git.

Huba answered 30/8, 2008 at 9:48 Comment(0)
D
5

Sometime last year I evaluated both git and hg for my own use, and decided to go with hg. I felt it looked like a cleaner solution, and worked better on more platforms at the time. It was mostly a toss-up, though.

More recently, I started using git because of git-svn and the ability to act as a Subversion client. This won me over and I've now switched completely to git. I think it's got a slightly higher learning curve (especially if you need to poke around the insides), but it really is a great system. I'm going to go read those two comparison articles that John posted now.

Detention answered 30/8, 2008 at 9:48 Comment(1)
Take a look at hgsubversion: bitbucket.org/durin42/hgsubversion. It currently requires a development version of Mercurial, but they will make a release for Mercurial 1.3, which is due July 1st.Boschbok
T
4

There is a great and exhaustive comparison tables and charts on git, Mercurial and Bazaar over at InfoQ's guide about DVCS.

Thaddeus answered 30/8, 2008 at 9:48 Comment(0)
V
4

I'm currently in the process of migrating from SVN to a DVCS (while blogging about my findings, my first real blogging effort...), and I've done a bit of research (=googling). As far as I can see you can do most of the things with both packages. It seems like git has a few more or better implemented advanced features, I do feel that the integration with windows is a bit better for mercurial, with TortoiseHg. I know there's Git Cheetah as well (I tried both), but the mercurial solution just feels more robust.

Seeing how they're both open-source (right?) I don't think either will be lacking important features. If something is important, people will ask for it, people will code it.

I think that for common practices, Git and Mercurial are more than sufficient. They both have big projects that use them (Git -> linux kernel, Mercurial -> Mozilla foundation projects, both among others of course), so I don't think either are really lacking something.

That being said, I am interested in what other people say about this, as it would make a great source for my blogging efforts ;-)

Vitreous answered 30/8, 2008 at 9:48 Comment(1)
Yes, they are both open-source projects.Boschbok
M
3

I realize this isn't a part of the answer, but on that note, I also think the availability of stable plugins for platforms like NetBeans and Eclipse play a part in which tool is a better fit for the task, or rather, which tool is the best fit for "you". That is, unless you really want to do it the CLI-way.

Both Eclipse (and everything based on it) and NetBeans sometimes have issues with remote file systems (such as SSH) and external updates of files; which is yet another reason why you want whatever you choose to work "seamlessly".

I'm trying to answer this question for myself right now too .. and I've boiled down the candidates to Git or Mercurial .. thank you all for providing useful inputs on this topic without going religious.

Monatomic answered 30/8, 2008 at 9:48 Comment(1)
+1, because the "seamless" experience is more important than people who don't work with these things think. A solid plugin for the IDE makes a lot of difference.Selfreproach
O
2

If you are migrating from SVN, use Mercurial as its syntax is MUCH more understandable for SVN users. Other than that, you can't go wrong with either. But do check GIT tutorial and HGinit before selecting one of them.

Osteen answered 30/8, 2008 at 9:48 Comment(0)
A
2

The mercurial website has a great description of the similarities and differences between the two systems, explaining the differences of vocabulary and underlying concepts. As a long time git user, it really helped my understand the Mercurial mindset.

Alabaster answered 30/8, 2008 at 9:48 Comment(0)
W
2

If you are interested in a performance comparison of Mercurial and Git have a look at this article. The conclusion is:

Git and Mercurial both turn in good numbers but make an interesting trade-off between speed and repository size. Mercurial is fast with both adds and modifications, and keeps repository growth under control at the same time. Git is also fast, but its repository grows very quickly with modified files until you repack — and those repacks can be very slow. But the packed repository is much smaller than Mercurial's.

Wards answered 30/8, 2008 at 9:48 Comment(0)
A
2

Yet another interesting comparison of mercurial and git: Mercurial vs Git. Main focus is on internals and their influence on branching process.

Aperient answered 30/8, 2008 at 9:48 Comment(0)
L
1

Some people think that VCS systems have to be complicated. They encourage inventing terms and concepts on the field. They would probably think that numerous PhDs on the subject would be interesting. Among those are probably the ones that designed Git.

Mercurial is designed with a different mentality. Developers should not care much about VCS, and they should instead spend their time on their main function: software engineering. Mercurial allows users to use and happily abuse the system without letting them make any non-recoverable mistakes.

Any professional tool must come with a clearly designed and intuitive CLI. Mercurial users can do most of the work by issuing simple commands without any strange options. In Git double dash, crazy options are the norm. Mercurial has a substantial advantage if you are a CLI person (and to be honest, any self-respecting Software Engineer should be).

To give an example, suppose you do a commit by mistake. You forgot to edit some files. To undo you action in Mercurial you simply type:

$ hg rollback

You then get a message that the system undos your last transaction.

In Git you have to type:

$ git reset --soft HEAD^

So ok suppose you have an idea what reset is about. But in addition you have to know what "--soft" and "--hard" resets are (any intuitive guesses?). Oh and of course don't forget the '^' character in the end! (now what in Ritchie's name is that...)

Mercurial's integration with 3rd party tools like kdiff3 and meld is much better as well. Generate your patches merge your branches without much fuss. Mercurial also includes a simple http server that you activate by typing

hg serve

And let others browse your repository.

The bottom line is, Git does what Mercurial does, in a much more complicated way and with a far inferior CLI. Use Git if you want to turn the VCS of your project into a scientific-research field. Use Mercurial if you want to get the VCS job done without caring much about it, and focus on your real tasks.

Laufer answered 30/8, 2008 at 9:48 Comment(2)
Actually you can alias commands in git, which makes the CLI less complicated to use. There are a bunch of them in this SuperUser (StackExchange) question.Thaddeus
Truly yes, you could also write shell scripts to deal with some common tasks. Eventually you begin to realize that you are building a wrapper CLI to deal with a VCS that has a badly designed and counter-intuitive CLI. And it is not only that. Git introduces an awful lot bunch of concepts with questionable usability that the user is eventually forced to learn and understand in order to feel comfortable with documentation and CLI messages.Laufer
I
1

This link may help you to understand the difference http://www.techtatva.com/2010/09/git-mercurial-and-bazaar-a-comparison/

Irrationality answered 30/8, 2008 at 9:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.