Junio C Hamano <gitster@xxxxxxxxx> writes: > 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 forgot that I was planning to expand on this part while writing the message I am following up. There are a few things you must take into account while designing a new format for a stash entry: - Your new feature will *NOT* be the last extension to the stash subsystem. Always leave room to other developers to extend it further, without breaking backward compatiblity when your new feature is int in use. - Even though you may have never encountered in your projects, higher stage entries can have duplicates. When merging two branches into your current branch, and there are three merge bases for such an octopus merge, the system (and the index format) is designed to allow a merge backend to store 3 stage #1 entries (because there are that many common ancestor versions in the example), 1 stage #2 entry (because there is only one "current brahch" a merge is made into) and 2 stage #3 entries (because there are that many other branches you are merging into the current branch), all for the same path. So, a design that says: A stash entry in the current system is recorded as a merge commit, whose tree represents the state of the tracked working tree files, whose first parent records the HEAD commit the stash entry was created on, and whose second parent records the tree that would have been created if "git write-tree" were done on the index when the stash entry was created. Optionally, it can have the third parent whose tree records the state of untracked files. Let's add three more parents. IOW, the fourth parent's tree records the result of "git write-tree" of the index after removing all the entries other than those at stage #1 and moving the remainder from stage #1 down to stage #0, and similarly the fifth is for stage #2 and the sixth is for stage #3. is bad at multiple counts. - It does not say what should happen to the third parent when this new "record unmerged state" feature is used without using the "record untracked paths" feature. - It does not allow multiple stage #1 and/or stage #3 entries. For the first point, I think a trick to record the same commit as the first parent may be a good hack to say "this is not used"; we might need to allow commit-tree not to complain about duplicate parents if we go that route. FOr the second one, there may be multiple solutions. A quick-and-dirty and obvious way may be to add only one new parent to the merge commit that represents a stash entry (i.e. the fourth parent). Make that new parent a merge of three commits, each of which represents what was in stage #1, stage #2 and stage #3 (we can reuse the second parent of the stash entry that usually records the index state to store stage #0 entries). As we allow multiple stage #1 or stage #3 entries in the index, and there is no fundamental reason why we should not allow multiple stage #2 entries, make each of these three commits able to represent multiple entries at the same stage, perhaps by - iterate over the index and count the maximum occurrence of the same path at the same stage #$n; - make that stage #$n commit a merge of that many parent commits. The tree recorded in that stage #$n commit can be an empty tree. I am not saying this is a good design. I am merely showing the expected level of detail when your design gets in a presentable shape and shared with the list. Have fun.