Kapil Jain <jkapil.cs@xxxxxxxxx> writes: > Plan to implement the project. > > Objective: > > Description: > > Implementation Idea: > > Relevant Discussions: > > Idea Execution Plan: Divided into 2 parts. Two things missing before implementation idea are design, and more importantly, the success criteria. What lets you and your mentor declare victory? As to the design, it does not quite matter if you add four or more separate trees to represent stage #[0123] entries in the index to the already octopus merge commit that represents a stash entry (i.e. when keeping the untracked ones, I think the stash entry's "result of the merge" tree records the state of the tracked files in the working tree, and the "result of the merge" commit records the the-current HEAD, a commit that records the state of the index and anothre commit that records the state of the untracked files, as its parents---that's already a 3-parent octopus). The fact that a stash entry is represented as a merge commit is a mere implementation detail, and there is *NO* need to worry about resolving merge conflicts while recording a stash. If the result of this GSoC task is to be any usable together with the current version in a backward compatible way, you must record these extra states as extra parents of the merge, so it is sort of given already that you'd be using some form of an octopus merge. The real challenge would be how the unstashing part of such a stash entry that records unmerged state should work. Personally I do not think it will be very useful to allow unstashing such a stash entry on top of any arbitrary commit---rather, I suspect that the user would want to come back to the exact HEAD the user had trouble resolving conflicts at, without having to first checking it out. IOW, a usual way to use "git stash" is $ git checkout topic $ edit edit edit ... I am happily hacking away ... ... the boss appears with an ultra-urgent task ... $ git stash save -m WIP $ git checkout master $ edit-and-build-and-test $ git commit ... now the emergency is over ... $ git checkout topic ... sync with the work others may have done on topic ... while I was dealing with the boss $ git pull --rebase origin topic $ git stash pop IOW, it is expected to be applied on top of an updated commit. But I have a moderately strong suspicion that a stash that holds unmerged state (i.e. a conflicted merge in progress) is created with a use case, which is very different from the normal use case, in mind. When creating such a stash entry, the above sequence would go more like this: $ git checkout topic $ git merge ... ... oops, conflicted, and it takes time to resolve ... $ edit edit inspect edit ... the boss appears $ git stash save -m "Merge in progress" $ git checkout master ... deal with the emergency the same way ... $ git checkout topic ... go back to the conflict resolution first without ... touching what may have happened on the branch in ... the meantime---a human brain cannot afford to deal ... with two or more parallel conflicts at the same ... time. $ git stash pop ... now deal with the conflict we were looking at ... before the boss interrupted us. $ edit inspect edit ... be satisfied with the result $ git commit ... now let's see if others have something else that ... is interesting $ git pull --rebase origin topic And if we assume that the primary use of a stash for a conflicted state is to bring us back to the exact state (rather than allowing us to pretend as if we started form a different HEAD), it might even make sense to teach "git stash pop" step to barf if HEAD does not match the first parent of the merge commit that represents the stash entry being applied (again, stash^{tree} is the working tree, stash^1 is then-current HEAD). That would make the application side a lot simpler and manageable by developers who are not intimately familiar with the code. Others may disagree with the above assumption (i.e. "a stash for a conflicted state does not have to be applicable), though, making your task a lot harder ;-). Quite honestly, I do not think you can design a system that attempts to "stash apply/pop" a recorded unmerged state on top of any arbitrary HEAD and leave a state useful for the end user to deal with when the "stash apply/pop" step itself introduces _new_ conflicts due to the differences between the then-current HEAD the stash entry is based on and the HEAD the "stash apply" is attempted on top of. Even the current "stash apply/pop with the change between the HEAD and the index" does punt when it cannot make a clean application, and that is without any unmerged entries in the recorded index state. The key point is "a state useful for the end user"---it is easy to build a system that claims to leave a state created from the updated HEAD and what's recorded in a stash entry that the end users cannot use as a stating point to make progress, but that is not something our users would want. Have fun.