It's that its porcelain is a clusterfuck. The staging area is a hack that greatly convolutes the UI, and it would have been better if it were left out and you just had a way to cherry-pick what you want to commit at commit time (if it wasn't everything).
There's no symmetry in commands. The opposite of "git commit" is "git reset --soft HEAD^", not "git uncommit". "git reset" is three commands in one. I could go on and on.
git was designed as a data model and then a series of slapdash commands that enabled manipulation of that data model. It wasn't designed from the end-user perspective backwards, and this really, really shows.
I love the staging area, and I miss it everytime I have to us SVN at work.
I actually use the GIT-SVN bridge to work with git locally, pushing my changes up to SVN when I've resolved a topic. I do this in part because of the staging area. I have accidentally included changes in SVN commits so many times that I try to avoid SVN altogether.
I agree though, so many of the commands are just plain painful, the reset command(s) is a perfect example.
You have it right that it was designed as a data model. Linus has said a few times that it wasn't originally intended to be the Source Control Management tool itself, but more like a kit for building an SCM. Sadly, it took off so quickly simply because Linus built it and was adopted as the end user solution.
I have really mixed feelings about the index, personally. It is nice to be able to incrementally build up a change, but I do think that it's a thing that complicates learning for new users.
I'm curious, as someone who actually loves it, what if there were just better tools for incrementally altering the last commit instead? I'm not sure that a more robust git commit --amend couldn't achieve the same goals as the index with less conceptual overhead.
You're basically railing against orthogonality. I don't think anybody disagrees that some flags could be made more consistent, but creating a separate git-uncommit when that functionality is fundamentally encompassed by the purpose of the third invocation of git-reset is a mistake.
If you make a specific case for 'git reset --hard/--soft HEAD^' then you would either be left without the more general (and more useful) 'git reset --hard/--soft <commit>', or you would have a situation where you have to use 'uncommit' to (for example) re-commit something, or you would be left with a git-uncommit command and still have git-reset for related operations. Why would any of that be better?
You could split the third invocation of git-reset off into its own command, but honestly I don't see the utility in doing that.
Disagree. A git-uncommit command tells you by its name what it's going to do, even if you know nothing about git or even if you don't know what a commit is, you can assume that git-uncommit will undo it.
git reset --hard tells you absolutely nothing obvious about what it's going to do unless you understand git and its specific incantations. You have to learn git commands, rather than intuit them.
-p, --patch
Interactively choose hunks of patch between the index and the work
tree and add them to the index. This gives the user a chance to
review the difference before adding modified contents to the index.
This effectively runs add --interactive, but bypasses the initial
command menu and directly jumps to the patch subcommand. See
“Interactive mode” for details.
I might not [EDIT: in fact, was not: see reply below] be appreciating the way that the staging area convolutes the UI for you, but you can pretend it doesn't exist by always just doing commit -a. And, if you want to "cherry-pick what you want to commit at commit time", well, that's what the staging area is for, isn't it?
Pretending it doesn't exist won't unconvolute the UI. I'm talking about things like "git checkout -- <file>", and "Git reset" which could just be one command if they didn't have to manage getting things in and out of the staging area.
I much prefer bzr's porcelain, it's much better designed and more sane.
There's no symmetry in commands. The opposite of "git commit" is "git reset --soft HEAD^", not "git uncommit". "git reset" is three commands in one. I could go on and on.
git was designed as a data model and then a series of slapdash commands that enabled manipulation of that data model. It wasn't designed from the end-user perspective backwards, and this really, really shows.