Christian Couder <chriscool@xxxxxxxxxxxxx> writes: > The purpose of this new option is to discard some of the last commits > but to keep current changes in the work tree. > > The use case is when you work on something and commit that work. And > then you work on something else that touches other files, but you don't > commit it yet. Then you realize that what you commited when you worked > on the first thing is not good or belongs to another branch. > > So you want to get rid of the previous commits (at least in the current > branch) but you want to make sure that you keep the changes you have in > the work tree. And you are pretty sure that your changes are independent > from what you previously commited, so you don't want the reset to > succeed if the previous commits changed a file that you also changed in > your work tree. > > The table below shows what happens when running "git reset --option > target" to reset the HEAD to another commit (as a special case "target" > could be the same as HEAD) in the cases where "--merge" and "--keep" > behave differently. I think this new option is unrelated to "--merge"; iow, the only relation to it is that it is an option to the same command "git reset", so it is related but it is related the same way and to the degree as "--mixed" is. Thinking about it even more, if the number of commits you are resetting away is zero in your use case (i.e. target is HEAD), shouldn't this new mode of operation degenerate to "--mixed"? So in that sense, it might make sense to contrast it with "--mixed". But let's try not to contrast it with anything else, and see how well it stands on its own. The below is my attempt. > working index HEAD target working index HEAD > ---------------------------------------------------- > A B C D --keep (disallowed) > A B C C --keep A C C > B B C D --keep (disallowed) > B B C C --keep B C C Let's give an explanation of the above in terms of what this means to the end users. When you have changes to a path that the accumulated commits between target..HEAD touch, you don't want to discard them. It doesn't matter if the changes in the work tree has been partially added (A != B) or fully added (A == B) to the index. In both cases, the operation is disallowed, just like "checkout $another_branch" stops in such a case. But if you have local modifications based on one version and dropping the accumulated commits between target..HEAD does not involve that path, we can safely "transplant" that change to the target. Presented this way, a future direction (iow, I am not suggesting you to do this before the current series solidifies) might be to allow users to do something similar to "checkout -m $the_other_branch". IOW, instead of disallowing "I have changed from C to B and switching to D" case, perform a three-way merge to bring the work tree file to (D+(B-C)), transplanting the local change you made on top of the target. > The following table shows what happens on unmerged entries: > > working index HEAD target working index HEAD > ---------------------------------------------------- > X U A B --keep (disallowed) > X U A A --keep X A A In a sense, this is consistent with the above; the local change attempted happens to be an unmerged result. But it is inconsistent with the intended use case you presented, which leaves no room for unmerged entries to enter in the index to begin with. It might be safer to error out on any unmerged entry in the index. I dunno. -- 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