I never understood that. I can do this just fine even with TortoiseSVN. Just click "commit" and select the files you want to include in this commit. I don't see how I need to keep yet another data structure / piece of "state" in the back of my head for that. I definitely don't see why I have to look for an alternate career because of that.
Am I missing something?
Yes. In git you can also do 'git add -p', which lets you interactively add pieces of a diff to the index, not just entire files.
Now, you could imagine an interface where you interactively select the pieces of the diff when committing, and I believe some VCSs do this. So, even though you were missing something, you weren't necessarily wrong. :)
But having the index can be useful if you want to build up the things you're going to commit over separate 'git add -p' sessions.
There's no need to imagine -- git-gui and git-cola can do this.
Click on a modified file, select specific lines from the diff, right-click, and click on "stage selected lines".
The interface is pretty simple: it just shows you each small piece of diff to the files you are adding, and you say whether you want to include that bit of diff in the index or leave it in the working directory. Alternately, it can drop you into a view of the diff in the editor, and you can add or modify diff lines as you please.
That's a correct argument for why the index has to be separate from your working directory. But I don't see why the index has to be separate from HEAD ... in my model, every "git add" would automatically be followed by an implicit "git commit --amend". So instead of building up your commit in the index you build it directly onto HEAD.
Since you're remotely sane, of course HEAD is a private branch not a public one (because you're perpetually modifying "history" on it). (And to start a new commit, of course you also need a command which advances HEAD by creating an empty commit.)
To put it another way, the index should be just another branch. The git commands are way too complex because they don't treat it orthogonally.
Also, it seems to me that git's behaviour encourages broken revisions (i.e. compiler errors, test failures) because your working directory doesn't match what you commit. And broken revisions will interfere with bisecting.
If you always want to commit everything use `git add . && git commit -a`.
With git, how you code is a non-issue. The whole idea is that you're able to to worry about commits afterwards. The index is a wonderful tool to help you untangle the mess of code that has not yet been separated into logical pieces. Working with git is not just writing out code and then committing it. Making proper commits requires time, discipline and practice.
Part of the problem might be the mindset that a VCS is supposed to record how the development happens, but if you think about it, that does not make much sense. The actual development process of a feature or even a bugfix is often riddled with experiments, trivial mistakes, sidetracking, and other largely uninteresting issues.
Once you have thought about what is logical to record into the repository and create a commit, you can test it. Git stash allows you to put aside all other work while you run tests, and git commit --amend allows you to fix the commit until it works.
Test your commits, and you will not have broken revisions or unbisectable history.
However, in practice i have seen those broken revisions in svn just as well. People forget to add untracked files or they skip the final unit test run. Basically, I believe your criticism is theoretical and no problem in practice.