tl;dr: the interface of mercurial may be more straightforward, but git won because it allowed people to work better.
tl;dr: the interface of mercurial may be more straightforward, but git won because it allowed people to work better.
I have to disagree about the index, though. I use Git every day, and i'm still struck by how pointless the index and the idea of staging is.
Ditto rebase. The routine use of rebase still seems completely wrongheaded to me. Mercurial's convention of preferring merges is better, and the last few years' developments around safe evolution of history really show rebase up as the misconceived hack it is.
Mercurial got 'commit --amend' a long time ago, but even before that, it had 'rollback', which undoes the last commit, leaving the working tree untouched (that is, with the state it had in the commit), so you can make your fixes and commit again.
I'd entertain the argument that Git won because it was better if even a handful of the people who now use Git had learned both Git and Mercurial and made an informed choice between them. That simply does not appear to be the case. Git got ahead because Linus invented it, and won because of GitHub.
This is probably more a symptom of the fact that either your workflow doesn't require an index or you don't understand its value.
Either way, the index is by far git's more popular and used feature, besides branches.
I use Git on a daily basis, but I never understood it.
If I just want to commit a specific part of my changes, I just do it. It's nice to see which files are staged for a commit, but I also see them in the commit msg comments.
They're called "hunks" in git parlance: sections of the file that define a "diff". A diff on a file can be made of multiple hunks.
Very often, my changes to a file are a mix of "fixing a serious bug" and "minor refactoring" and "removing dead code". When the time to commit comes, git makes it trivial to separate all these changes in different commits so that each commit does one thing and one thing only.
I can't tell you how many times I've shot myself in the foot accidentally committing stuff to svn when I just meant a single file.
I find it amazingly useful. The staging area is for building your commit. I always ever use -p (ie., "add -p", "reset -p" and "checkout -p") and use it to construct the commit out of parts.
The way I work, I split my current work into multiple commits. I may have implemented a feature, fixed a bug I found along the way in the same file, and updated the readme with something unrelated; those are three separate commits. I do "add -p" to pick the fragments, and when I'm happy, I commit. Repeat until repo is clean.
Sometimes, my current work results in a whole bunch of such commits. Sometimes I have to split part of my current work into a separate branch. Again: Stage stuff, stash -k, checkout new branch, commit as a WIP commit, go back, unstash.
Darcs has "record", which is like "add -p" except it also commits at the same time, and back when I was using it, I remember hating the fact that it required that everything had to be recorded in one go. Git's incremental staging area is much more pleasant because you don't get stressed out by the impending commit that is looming over you.
One thing I really like about git is that it lets me be mindful of my actions in a way that hg didn't seem to encourage. In return, it gives me what feels like True Power to recover from _any_ mistake. Wrong branch? Accidentally merged (and pushed) my master branch? No problem, they're just bookmarks to commits anyways.
Mercurial, by contrast, felt Rather Convenient, with occasional chasms of despair if you strayed too far from the path. It's possible that my high opinion of Git is mainly from the fact that it forced me to learn more, but it really feels more flexible. I always have the right tool for whatever I need, and I know why and how to use them.
I think you also underestimate the developer community (or may I overestimate them.) Regardless, my anecdotal evidence is that I did try HG and Git, and while I preferred HG when I first started evaluating them, as soon as I found out how to use Git branches, it was all over for HG. At work we currently inherited a project in HG and everyone that has to work on it complains about it. Some know Git, some are .Net or even old school CVS/SVN people (our VCS migration took a bit longer than it should have), but it doesn't matter. HG = hard to use for them, whereas Git make sense after getting over the initial hurdles. I see the same kind of path I took, where at first they are like, oh, Hg isn't bad, and then after using both, choosing Git as their preference.
Rebase is a hack? Rebase copies a series of commits on top of an immutable history at a certain point in time. This allows you to deal with merges a single conflict at a time, instead of dealing with all the conflicts at once with a merge. It also allows you to avoid cluttering your history with useless merge-commits when just syncing with another repo.
Merges have their place. I use them whenever I merge branches, using --no-ff so I can attach a "Fixes issue #77" in the merge commit message. Of course, before I do that, I sync the branch I'm merging into, then rebase on top of that (to have a clean merge). I might also rebase --interactive to clean up the commits of my branch, so that the history is as easy to read as possible.
Comparing rebase to rollback is wrong. Git has rollback (or revert) as well, and it's used for other usecases, like when reverting changes on a public branch (where rebase would fuck it up for everyone).
I'm sorry, but your comments make it sound like you don't really understand Git.
Not sure what you mean by 'deal with a single conflict at a time'. To rebase or merge, you will have to resolve all conflicts that merge/rebase produce, right?
It's easier to remember the intended behaviour when the code changes are as small as possible, and when you have a (hopefully) good commit message to look at.
If you are concerned about reading history, then a merge can give you more context regarding the commits. With re base, commits will jump between features. For example, You are looking at commit for feature 1, but the next series of commits are for a bug fix in feature 2. Next series of commits belong to minor tweaks in feature 3..
Regarding the "rebase, commits will jump between features" part: that really depends on how you do things. On my projects, we use git flow. In such a scheme, every branch you would rebase, belongs to the same feature or bugfix.
Not sure if I made that clear. But I was talking about the result of the rebase. Once you rebase, all the commits that were in different branch ends up being back to back, and hence become interleaved...
This is quite subjective. A more probable reason is that git is popular because of github..
And once git gained some popularity, people started viewing other DVCS as inferior because they were doing things differently from Git. For eg, the branching in Mercurial. People are appalled when they see how named branches can be done in Mercurial. Without going into any thought or reflection on how Mercurial's named branching can be useful in certain situations, they call it braindead. But actually git's branching is quite simple and less powerful than the methods offered by Mercurial. Less powerful, because Mercurial offers multiple methods to make a branch so that you can use the right one for a particular situtation. Note that this actually asks for more experience from the user. He needs to have experience with using each of these methods and should know how each of them may be useful in the future. It also stores more metadata and tools like revset which lets you to build powerful queries. So in that sense, Mercurial is also more complex than Git. But that is in a good way and unlike git's, it is not the complexity that gets in your way.
So in short, I think git is actually quite simple than Mercurial, but hides that simplicity behind a complex interface with non-intuitive naming and weird combination of flags and stuff. This causes the 'Aha' moments when one can finally see the simplicity that hides behind that interface, which trigger a huge release of Dopamine and prompts the user to write his own set of Git revelations that (used to) flood the internet, which in turn increases the popularity of Git...