As Scott Chacon (author of ProGit) puts it,it's really not that huge a deal if your using Git or Mercurial; they're very similar--it's using a distributed version control system that's a huge deal. Many many places are still locked into old school, centralized systems that make collaboration much harder than it is using Mercurial or Git

Many many places are still locked into old school, centralized systems that make collaboration much harder than it is using Mercurial or Git

That makes me chuckle because what is Github? A centralized system. If your commits aren't pushed to Github, they don't exist as far as the rest of the world is concerned. That sounds shockingly familiar to svn.

Git has the appearance of more power. People believe you can do more with it, when in reality, 99% of the things you're going to spend most of your time in a VCS doing, Git and Mercurial are pretty equivalent. They may do things differently, but they achieve the tasks roughly equally well.

I like git just because of it's distributed nature, and I use over HG because I saw it first, but I'm glad I don't have to do complex operations with it because it's not elegant (at least for me, a lowly non-vim using programmer) and dread the day I have to use it professionally.

I've been using mercurial for two years and I'm loving it. It was an extremely easy switch from SVN as the cli tools have a quite similar syntax. Our company has 20+ repos using mercurial and I can't recall a single one going fubar/breaking as a result of vcs or user failure. The only issue we've had is the slowness and excess resource usage when pulling/updating huge repos.

For comparison we have one huge git repository I have to say git is extremely fast, but the speed comes with a price as the tools are a bit more difficult to use and user errors can be tricky to correct. The repo in question broke once and required some "black magic" to fix.

I'd say git is fast as hell but hard to use, mercurial is slow but it just works.

I'd say git is fast as hell but hard to use, mercurial is slow but it just works.

I think it would be more accurate to say that git requires you to learn it and think in its terms to be useful. Once you've made that jump, everything is pretty straightforward, but if you want something that "just works" or something that's intuitive given familiarity with other VCS concepts, you'll be sorely disappointed.

My list of projects has "learn LISP" and "learn Prolog" and "learn ARM"... it'll be a long time before "learn Git" gets to the top. Thank you for your comparison, it has confirmed that Mercurial is the right DVCS for me.

[the git index] encourages people to check in changesets that contain code which they’ve never tested.

Those people are sloppy! The git index also lets you do partial commits and rollbacks on your current working set. Those tools help you to avoid making monolithic "Fixed some stuff" commits, and in my humble opinion I'd rather have to bisect through a dozen non-building commits than to have bisect lead me to a gigantic +1000/-200 commit.

Haha, yes! git stash is perfect for splitting up commits and testing them separately. It helps tremendously when you're in five fixes deep and you need to back out to the first layer.

Another nifty thing to do with git stash is to add a few things to the index before stashing. Then, since stash adds one stash-commit for the working tree plus another stash-commit for the index, you can cherry-pick the index part of the stash back onto your working tree without officially committing it.

It appear that the author of the article posted by OP isn't very familiar with Mercurial, and severely misconstrues its branching abilities. Which… kind of renders many of his points moot.

Your article on Mercurial branching is excellent, and helped me a great deal when I was learning the system. Though to be honest, (a) some aspects are now a little outdated and (b) I do think that it's possible to rearrange some of the core concepts in such a way that it's even easier for the novice to grasp. (I've taught some in-house Hg courses and have been experimenting with the best way to convey the information.)

This article is good, it highlights the Mercurial style of branching, and how bookmarks is a good alternative to git's local branches. Mercurial's global branches is also probably easier to grasp for converts from archaic systems like SVN.

I am one of those occasional Mercurial users with a Git background who almost wrecked a remote repository with loads of local test-branches. I ended up cloning from scratch and using cp to get rid of them and do my commit again.

Your article also spells out why I love Mercurial so much: the elegance of the command line syntax. Each command does one thing, there is little overlap between them, and it makes sense. Git is a mess of options.

I'd disagree with the statement: "GitHub is leaps and bounds above BitBucket in pretty much any aspect you look at".

Bitbucket supports unlimited free private repositories. GitHub does not. For me that was the deal breaker. You are paying $12 a month for 10 private repos and 5 contributors on GitHub (which is still worse than the free bitbucket plan).

And I'm not really too sure brining bitbucket or github into the equation is really relevant. Bitbucket certainly supports git. I'd be very surprised if GitHub didn't also support hg in some form.

The big thing for me is that git is transparent, while mercurial isn't. A git user should learn how git works internally, and is rewarded immensely. And it's really not that much work.

Anyway, mercurial branches are different enough from git branches that it doesn't even make sense to compare them. A git branch is a literal branch in the DAG. Merges are points where two branches join. Everything can be identified uniquely by pointing to a commit; no special branch recording mechanism is needed.

A git branch having two heads is a conceptual oxymoron. That would be two branches by definition.

In the data structure, a new branch occurs when you have two commits that share a parent. One of these commits might be pointed to by "master" and the other pointed to by "dev". You can easily delete the "dev" pointer and the branch will remain in the data structure.

However, without a reference or a dependency on it, git will consider it unneeded when the next gc happens. Until then, you're free to look at the reflog and create a new reference to it. You can destroy branches and screw up your repository as much as you want and as long as you don't git gc or actually delete anything under .git/, you cannot lose data that has been once committed.

When you "git push", it might be possible to somehow transport all commits over the network, but without an accompanying reference, it's not very useful.

The big thing for me is that git is transparent, while mercurial isn't. A git user should learn how git works internally, and is rewarded immensely. And it's really not that much work.

The entire point of creating tools and abstractions is so you don't have to think about the low level details of how they work to use them. A tool that forces you to learn how it happens to be implemented internally and keep that in your head to use it effectively is a shitty tool.

People like to say "Git's not a VCS, it's a tool for working with DAGs on the filesystem and it's great for that!" but in the real world it's marketed as and used as a version control system.

Anyway, mercurial branches are different enough from git branches that it doesn't even make sense to compare them. A git branch is a literal branch in the DAG. Merges are points where two branches join. Everything can be identified uniquely by pointing to a commit; no special branch recording mechanism is needed.

A git branch having two heads is a conceptual oxymoron. That would be two branches by definition.

Right, so when I say that Git doesn't let you push two heads to a branch like Mercurial, it truly is a limitation of Git's branching model (or "branching UI" if you prefer to call the branch refs that and consider the "branching model" to be the DAG).

Git forces you to create a new name every time your history happens to diverge, where Mercurial is happy to let you work directly with the DAG using hashes/numbers.

Yes, you can use hashes and "detached HEAD" mode to work directory on the DAG in Git, but this sucks because:

It's clumsy (lol just grep the reflog all the time, and you didn't really need log --graph right?).

Like you mentioned, Git will helpfully delete your data if you work on another project for a while.

The other effect of Git's branching model is that you can't really tell what branch a commit was originally made on once you've merged its branch with another. For example in Mercurial you can do:

hg log --rev 'branch(stable) and not merge() and ancestors(1.6) and descendants(1.5)'

To see all the non-merge commits made on the stable branch between 1.5 and 1.6. With Git there's no way to tell if a commit was made on the stable branch if it's been merged since it was made.

This is usually just a minor inconvenience, until someone merges something into the wrong branch accidentally and a few days later you're wondering what the hell happened.

The benefit to Git's branching scheme/model/ui/whatever is that branches in Git are easy to remove once you're done with them, while branches in Mercurial are much more difficult to get rid of. Mercurial tries to fix that with bookmarks, but honestly they don't feel quite as nice as Git's branches to me.

I feel like some kind of hybrid of these two could provide a nice middle ground, but haven't thought too much about it.

A slight aside -- I'm fairly certain that the reason git "forces" you to create a new name when creating a new head (in hg terms) is because if your history diverges, it presumably diverges for some reason, and you could probably do with a label for it, you forgetful human you.

I don't know why hg people who like multiple heads like them so much (and so vehemently). I use bookmarks extensively when I use hg, mostly because I don't mind half a second to type a name as opposed to upping to an old commit, coding, doing that a time or two and forgetting where I am. There are times where I won't use a bookmark because I know that head will only exist for a minute or so, but it's such a minor inconvenience that I would strongly prefer to have to take action to not put a label of some sort on a new head.

Maybe you, or someone else, can explain just what use cases unnamed heads have, other than the use case of not feeling like typing a name? I feel like the level of emotion that I see people defend them with makes it probable that either I'm missing something really useful out of ignorance or lack of need, or that it just attracts a very specific type of person.

Right, Mercurial is more like a product, whereas Git is a pile of code and if you don't understand how it works it's because you aren't smart or didn't try hard enough. It's a pretty significant difference in attitudes, though not a very surprising one given each tool's provenance.

There are a number of commonalities between git and mercurial: they are both version control systems; they both refer to their revisions with hashes; they both represent history as Directed Acyclic Graphs (DAGs); they both offer a lot of high level functionality like bisect, history rewriting, branches, and selective commits.

And they are both distributed. IMO that's by far the biggest similarity.

Perhaps, but it's a bit misleading when the title of your article is "The Real Difference Between Git and Mercurial". I expect a "Real Difference". In bold 32 px font.

Another commenter pointed out what the listed Difference is, but I feel the author should've using the full disposal of formatting tools available to him - it really makes a difference when trying to make a point.

I read the whole article. I thought it was possible to figure out what "the" difference is, but the author wasn't very explicit about it.

Anyway, the central thesis didn't convince me. Both tools use a data structure that can recreate any revision if a file. They use different methods of eliminating redundancy, but fundamentally eliminating redundancy just means you have (purpose-built) data compression. As far as what the file formats can do, they seem to be equivalent. I thus wasn't entirely convinced that differing data models is the reason mercurial "can't" work as conveniently. Maybe it's true, but it seems like a more compelling explanation is possible.

I've found git to be more pleasant to work with. Stash is invaluable, and history rewriting lets me have more sensible commits to push into the "authoritative" repo. You can do the same in mercurial with plugins, but there are all sorts of fnords that get thrown at you when you try to mess with the timeline.

In the past, I've found Mercurial better to work with, mainly because it's Windows support is first class, as opposed to git's, where it was fairly poor (I can't speak for recently). Especially with regards to tools like TortoiseHg. TortoiseGit exists, but it felt like it didn't really belong.

I skimmed it, which is what you should expect of your reading when publishing on the web, at least if your audience is Redditors. We are consuming vast amounts of information, and, in general, don't read as carefully as we would if parsing a requirements document.

I agree that this is unfortunate, but it is the current state of things, and a content provider should take it into account. Understanding your audience is an important part of good writing.

As far as I know, there are cases in mercurial where you can’t get back to where you were. Because solving a problem in mercurial generally creates another commit, it can be hard in some cases to say, “put me back to the moment exactly before I screwed everything else up”.

WTF? I don't think this guy has used hg and simply has been browsing the documentation and hasn't found how to do what he's talking about.

I use TortoiseHG and if I want to go back to a previous commit I just start up the workbench which shows all my commits, right-click the one I want to go back back to and click 'Update' and I'm there.

What are the cases in mercurial where you can't get back to where you were? That's a pretty damning issue and I'd drop hg in a heartbeat if it couldn't do something as simple as that.

You probably should have clicked on the link in that paragraph. Going back to any past revision is trivial, and always works; the problem is when you've done something like a merge, which creates a commit, and then you want to remove that commit from your repository.

After a trivial merge, one tends to trust the result of the merge. We now learned mixing cherry picks with merges is a very big problem in git, mercurial, etc. In darcs, there would be no problem -- as darcs would know that the patch is the same in both branches, and see that the revert is newer than both.

A merge in git doesn't look at the entire set of changes in both of the merges ancestries. It does not see the change and the revert -- and compares that with the change. It only sees a nothing on one side, and the change on the other.

I maintain a large collection of configuration files. Some of these are quite permanent in their nature and development, and git/hg would work just fine. Over half of them are for short term only, to get a job done and deleted.

With darcs I can add these to the repository, and obliterate them once they became obsolete. Having them in the history would be just clutter. If I really wanted to, I could just save the changes as a patch file and back it up.

With DAG based system, you can't pull out changes in between. If I was using git or hg, I probably would live with that clutter, since the alternatives are not attractive. Managing multiple repositories separately is not the way I want to work.

This was a known bug in darcs 1, can you reproduce this with version 2? The redesign of the repository format was supposed to take care of it. Being a solo dev I don't have so much conflicts that this would be an issue for me.

Having the VCS try to decide which changes depend on which others sounds like a recipe for unexpected bugs.

Heh - that reminds me of the way some former co-workers of mine used to protest the idea of using those crazy new merge-model VCSs (eg. CVS/Subversion) instead of the good old locking-model VCSs (eg. Visual SourceSafe or PVCS). They just didn't trust that the merge-model VCS wouldn't somehow fuck up their code, whereas they had the reassuring illusion of control in the locking-model VCS.

Hmm, that's not what the video wanted to show. You can manually specify when a patch depends on another, of course (you just don't have to when it's obvious). The greatest advantage of darcs is that you don't have to care about branches, or if some of your files are a little different from the repository : most of the time, it doesn't matter, darcs can merge the files anyway.

I don't know for the bugs (I use darcs with a small team, on applications that are quickly developed and delivered to the clients, and it works fine), but if darcs 1 was, indeed, painfully slow on medium repos, darcs 2 seems to be fast enough for us.

Relevant to the Darcs theme, there is a project called vng, which is essentially the Darcs UI but for Git repos. It's quite nice, I used it for a while when I was less familiar with the git UI (though now I've mainly switched to using Mercurial, working with Git repos via hg-git).

There were also quite a few Git "porcelains" 4-5 years ago (ie. tools intended to provide a friendly easier-to-use UI to Git functionality), though most of them seem to have faded away now as Git itself has become easier to use.

Perforce is pretty cool in a bunch of ways, but try branching the repo. Let me know how many hours is takes to figure out a branch. Then let me know how many days it takes you to integrate that branch into the mainline.