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