Junio C Hamano <gitster@xxxxxxxxx> writes: > * cc/reset-keep (2010-01-19) 5 commits > - reset: disallow using --keep when there are unmerged entries > - reset: disallow "reset --keep" outside a work tree > - Documentation: reset: describe new "--keep" option > - reset: add test cases for "--keep" option > - reset: add option "--keep" to "git reset" > > I am not sure if this series is useful, and even less sure if the > usefulness of it outweighs the confusion factor. Regarding this, I've been thinking about how I would explain this new feature to end users (both new ones and old timers) as a good addition. I still haven't reached a satisfactory explanation, but here is my "WIP" try to describe a scenario. I understand that in essense, "reset --keep" does exactly a "checkout <commit>" does but without detaching the HEAD. I often deliberately stay on detached HEAD because I find it highly useful that I can jump around freely with "checkout <commit>" once the head is detached (I would stay in a detached HEAD state and keep local changes around). I think there must be a similar usefulness I can gain by "reset --keep". But I am not really succeeding to explain that to potential users. I have built commits A, B and C on my 'topic' branch, and the contents in the working tree is a checkout of C (which is at the tip of the branch). I can make a small improvement, and start hacking. And then I realize that the change I just did, which I haven't committed nor even added, is an improvement to commit A. I could do: $ git checkout topic~2 ;# to detach at A $ git commit --amend -a ;# to improve on A $ git rebase --onto HEAD @{1} topic ;# rebase the rest and come back to fix up A and rebuild B and C on top of it. With "reset --keep", I could do this instead: $ last=$(git rev-parse HEAD) $ git reset --keep topic~2 $ git commit --amend -a $ git rebase --onto HEAD @{1} @{2} ;# rebase the reset $ git branch -f topic ;# and come $ git checkout topic ;# back The above however is clearly not an improvement. So far, the _only_ use case I can think of that "reset --keep" may be superiour than anything existing is this: I have built commits A, B and C on my 'topic' branch, and the contents in the working tree is a checkout of C (which is at the tip of the branch). I can make a small improvement, and start hacking. And then I realize that the change I just did, which I haven't committed nor even added, is an improvement to commit A. Also I realize that B and C are completely bogus, and I want to get rid of them. I could do: $ git checkout topic~2 ;# to detach at A $ git commit --amend -a ;# fix it $ git branch -f topic ;# the rest I do not need $ git checkout topic ;# and now on the branch but it would be far easier if I can do this: $ git reset --keep topic~2 $ git commit --amend -a You have some addition in Documentation/git-reset.txt in this topic, and the last example (starting at around line 350) may be describing this situation, but it was not very clear to me. Keep changes in working tree while discarding some previous commits:: Suppose you are working on something and you commit it, and then you continue working a bit more, but now you think that what you have in your working tree should be in another branch that has nothing to do with what you commited previously. You can start a new branch and reset it while keeping the changes in your work tree. ------------ $ git tag start $ git branch branch1 I take it that this is supposed to be "checkout -b branch1". $ edit $ git commit ... <1> $ edit $ git branch branch2 <2> I take it that this is supposed to be "checkout -b branch2". $ git reset --keep start <3> ------------ <1> This commits your first edits in branch1. <2> This creates branch2, but unfortunately it contains the previous commit that you don't want in this branch. <3> This removes the unwanted previous commit, but this keeps the changes in your working tree. The above sequence is not very convincing. After you edited the second time, you create branch2 and that is presumably because you realized that the change in the work tree belongs to a separate topic. It would be a lot more natural to do this: $ git tag start ;# we do not have to tag, but just to make the remainder of the illustration easier to read... $ git checkout -b branch1 $ edit ;# do the work for the first topic $ git commit ;# and commit $ edit ;# start working more and then realize that the change belongs to a separate topic, and the previous commit is unrelated to that new topic $ git checkout -b branch2 start $ edit ;# continue working $ git commit ;# and conclude it so the example makes the use of "reset --keep" look artificial. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html