I had a recent epiphany about staging, which is that it really starts making sense if you stage as you go.
Let's say you want to write small feature X, and it truly makes sense for X to be a single commit. But doing X involves changing around both Y and Z. Git makes the following workflow easy:
* Fiddle around until you get Y working how you want it
* Stage it
* Fiddle around trying to get Z to work. Try something experimental. Nope, that's not you want it. `git checkout .` Try again.
You don't have to worry about only blasting away the failed Z attempt while preserving Y—since Y is staged, it's easy to keep around.
Technically the same metaphor can be used for "commit" if we assume you stage the one thing and commit that one thing. Now look through the same workflow again but replace "stage" with "stage it and commit it."
If you don't have `stage` how are you going to generate a commit which has only some of the changes you've done (potentially including partial commits from files)?
`stage` is unnecessary if you have a really simple workflow, but it provides a lot of flexibility at very little cognitive cost.
By specifying the parts you want to include when you commit. I think it's unnecessary for any reasonable work flow, and doesn't manage to break even on its benefit vs. cognitive cost.
"git add -p" generally negates the need for incremental staging, unless you have made two unrelated changes to the same diff hunks that need to be untangled.
Let's say you want to write small feature X, and it truly makes sense for X to be a single commit. But doing X involves changing around both Y and Z. Git makes the following workflow easy:
* Fiddle around until you get Y working how you want it
* Stage it
* Fiddle around trying to get Z to work. Try something experimental. Nope, that's not you want it. `git checkout .` Try again.
You don't have to worry about only blasting away the failed Z attempt while preserving Y—since Y is staged, it's easy to keep around.