From: Jonathan Nieder Date: Thu, 31 Mar 2011 18:42:46 GMT Subject: Re: [PATCH] reset: update help text Message-ID: <20110331184246.GA19264@elie> In-Reply-To: Nguyen Thai Ngoc Duy wrote: > To be honest, I have no idea what the above describes. I read 9bc454d > (reset: add option "--keep" to "git reset" - 2010-01-19) and figured > that --keep is like --merge except that "git diff" before and after > the reset is exactly the same, is it? I have never used --keep before. I use "git reset --keep" to - discard a bad commit: git reset --keep HEAD^ - start working against a different commit: git checkout -b topic && ... hack hack hack without committing ... && : "oops, I thought I was on master but I was somewhere else" && git reset --keep master The spirit of the thing[1] is: * if the diff "HEAD -> " touch paths in which we have local changes, error out; * otherwise, checkout the relevant paths from but leave the paths in which we have local changes alone. which indeed means "git diff --cached" and "git diff" before and after would be exactly the same. But there are some edge cases, in which the diff "HEAD -> " makes the same change we did and the reset --keep is still allowed. This is totally different from --merge. The only legitimate use of --merge is to cancel a merge you just performed, imho --- the effect otherwise is too scary ("git add ; git reset --merge elsewhere" --- bye, bye, changes made at ). Hope that helps, Jonathan [1] Detailed semantics: for each path listed by "git diff --name-only HEAD ": * if the worktree, index, and HEAD match, make the index and worktree match . * otherwise, if it is "not easy" to keep local changes, error out. We are not going to do a three-way merge. That is, - if the index matches neither HEAD nor , error out; - if the index matches HEAD but not the worktree, error out. * otherwise, it is "easy", so keep local changes. - if the index already matches , leave the index and worktree alone. - if the index and worktree match HEAD, make them match the instead. These are the same rules used by fast-forward merges and plain "git checkout".