Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I like the staging area, though–at any given time I always have code that I do not want to put in a commit object (perhaps I changed some build flags, or my IDE touched some files I don't care for, or…) However, I do agree 100% that all the terminology is pretty bad.


The sin of Git's staging area is that Git forces it into the default interaction path—requiring you to take it into consideration whether or not you're interested in only committing some of the changes. Git should default to including all changes, and iff you direct it to (i.e. by explicitly specifying `git add`) should you have to take into consideration the notion that some changes are staged and others aren't.


I'm generally also one of the git sceptics - Though I loved staging for a while as for the fine grained control. `git add --all` just might not do the right thing - for paranoids like me. Just recently got to know you can skip the staging by appending the paths of the changed files you want to commit after `git commit -m "awesome commit"` - neat.


You can skip the explicit staging using

  git commit --patch
then interactively select the specific changes by diff hunk.

It combines with --amend.


Would you like the staging area less if it was an object of exactly the same type as a commit, referenced by CHEAD (commit head) instead of HEAD?


Only the workspace can be built and tested, so the workspace is what should be committed. We should be stashing anything we don't want to test and commit yet.


I'm trying to keep out of this fight, but how are you planning on just stashing one hunk without staging?


The stash is another feature that should use the regular commit representation. Well, somehow. Yes, the stash is different in that it preserves (or can preserve) uncommitted changes, as well as staged changes, and it can tell these apart.

However, if the staging area is relaced by a CHEAD commit ("commit head") whose parent is HEAD, then the problem of "stashing the index" completely goes away. You don't stash staged changes because they are already committed into the staging commit CHEAD.

That said, the stash feature could work with this CHEAD. Stashing the staged changes sitting in CHEAD could propagate them into the stash somehow (such as by a reference to that commmit). Then CHEAD is reset to point to HEAD, and the changes are gone. A single stash item consisting of work tree changes and staged changes could simply be an object that references two commits: a commit of working changes committed just for the stash, and a reference to the CHEAD which existed at that time. It could be that one is the parent of the other. So that is to say, a commit is made of the working copy changes, parented at the CHEAD. The stash then points to the SHA of that commit.

Intuitively, I know this would work, because in the existing Git, I could easily implement this workflow instead of using the stash. Given a tree of local changes, I could "stage" some of them by creating a commit with "git commit --patch". Then "stash" rest of them into another commit "git commit -a". Then, create a branch or tag for that two-commit combo, and finally get rid of it with "git reset --hard HEAD^^". Later, I could easily recover the changes from that branch, either by cherry picking, or doing a hard reset to them or whatever.

Speaking of which, an example of how stashes are limiting because they aren't commits, think of how you can't do:

   git reset --hard stash@{0}  # wipe it all away and make it like this stash
You can't do that because a "reset --hard anything" cannot reproduce a state where you have outstanding working copy changes and/or an uncommitted index, but "stash apply" or "stash pop" are saddled with that requirement.

The requirement of reproducing working changes and staged ones from a stash represented as a two-commit combo is very simple. You cherry pick one normally and make it the CHEAD (the aforementioned special head for pointing to a commit being staged). Then the other one is cherry-picked with -n, so it is applied as local changes.


“git stash push --patch” lets you choose hunks to copy into the new stash and clean out of the workspace. It’s pretty similar to “git add --patch” for choosing hunks to stage.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: