Jeff King <peff@xxxxxxxx> writes: > On Sun, Jul 01, 2007 at 06:06:29PM +0900, しらいしななこ wrote: > >> I don't understand myself anymore, either (^_^;) I just tried to follow >> Jnio's earlier suggestion in his message. He said this. > > OK, we will wait for Junio to clarify tomorrow. :) Jeez. I tried to stay lazy and have all the work done by somebody else (and taking the credit at the end, as I was mentored by you-know-who ;-), but you guys managed to suck me into this. There are a few issues when you replay a stash on a state that is different from the state the stash was created on. Stash records the then-current HEAD, index and the working tree (I'll call them H, I and W for brevity from now on). Ideally, we would want to have the difference between the resulting index and working tree to be similar to the difference between I and W. Replaying the stash is done on a clean working tree. That is, we require that at least the index and working tree match (we could also require that the index and HEAD match, but I do not think it changes anything in this discussion). And we apply the change between H and W with three-way merge. For paths that are cleanly merged with this three-way merge, merge-recursive updates the working tree and the index. That means if you do "git diff", you would not see the local changes that were carried forward would not be visible, and you would need "git diff HEAD" to view them. I found it confusing, and that was the suggestion I sent was about. Nana's "3rd try", which I applied and pushed to 'next', addresses this issue by running "read-tree --reset $c_tree" (where $c_tree is the contents of the index before replaying the stash). This is not ideal. We would want to see "git diff" for such a path show difference similar to difference between I and W. There is a little glitch, though. Such an operation can also be done with a three-way merge (git-merge-file would most likely be useful), but what would we do when this second merge conflicts? If we insist on making the "git diff" output to match the diff between I and W for the path, somebody needs to resolve the conflict and put the result in the index, but if git-merge-file couldn't, the user is left to do that. I strongly suspect that we would not want that aggravation (besides, the working tree cannot be used anymore as it contains what we would want to leave there as the result of unstashing). The second best thing is probably to leave the index as it was before the stash was applied for such a path (in other words, for such a path, we discard the difference between I and W, favoring to use W). We could still attempt to carry the difference between I and W for paths that the second merge cleanly resolves, but then "git diff" will show full diff between H and W for some paths (that is, the ones the second merge did not cleanly resolve) while diff between I and W for others (the ones that resolved cleanly). That is not what the current code does, though. I am hoping that the "best effort" would make it more convenient to use, but I also suspect that it might make things more confusing to the end user and certainly more difficult to explain. So that's about the cleanly-merged case. What we should do about the paths that the first merge (i.e. the one that updates the working tree) does not resolve cleanly? We would want to keep the index the way merge-recursive left, for conflicting paths at least. We would have higher stages for them, so that the user will not accidentally commit things that have not been merged, and can use usual conflict resolution techniques like "git diff" to view the combined diff between three versions. - 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