On Wed, Mar 20, 2019 at 7:24 AM Junio C Hamano <gitster@xxxxxxxxx> wrote: > > Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> writes: > > > If you have staged changes in path A and perform 'checkout > > --merge' (which could result in conflicts in a totally unrelated path > > B), changes in A will be gone. Which is unexpected. We are supposed > > to keep all changes, or kick and scream otherwise. > > > > This is the result of how --merge is implemented, from the very first > > day in 1be0659efc (checkout: merge local modifications while switching > > branches., 2006-01-12): > > > > 1. a merge is done, unmerged entries are collected > > 2. a hard switch to a new branch is done, then unmerged entries added > > back > > > > There is no trivial fix for this. Going with 3-way merge one file at a > > time loses rename detection. Going with 3-way merge by trees requires > > teaching the algorithm to pick up staged changes. And even if we detect > > staged changes with --merge and abort for safety, an option to continue > > --merge is very weird. Such an option would keep worktree changes, but > > drop staged changes. > > I think "checkout -m <otherbranch>" with a dirty index should refuse > to run; there is nothing to "continue" after such a failure, so I am > not sure what you mean by "an option to continue" (iow, I do not see > a need for such an option, and if that option makes the whole notion > strange, we can just decide not to have it, can't we?). We have --force to continue even when we have local changes, which will be overwritten. I was thinking a similar option which gives us permission to destroy staged changes. Refusing to run fails the test suite though (I tried that even before this patch), in t7201.10, "switch to another branch while carrying a deletion", because of this line git rm two -- Duy