On Fri, Sep 23, 2016 at 2:13 PM, Johannes Schindelin <Johannes.Schindelin@xxxxxx> wrote: > Hi Stefan, > > On Fri, 23 Sep 2016, Stefan Haller wrote: > >> Stefan Beller <sbeller@xxxxxxxxxx> wrote: >> >> > On Thu, Sep 22, 2016 at 12:48 PM, Kevin Daudt <me@xxxxxxxxx> wrote: >> > > On Thu, Sep 22, 2016 at 07:33:11PM +0000, Anatoly Borodin wrote: >> > >> Hi Stefan, >> > >> >> > >> this section was added to the manual in the commit >> > >> cddb42d2c58a9de9b2b5ef68817778e7afaace3e by "Jonathan Nieder" >> > >> <jrnieder@xxxxxxxxx> 6 years ago. Maybe he remembers better? >> > >> >> > > >> > > Just to make it clear, this section explicitly talks about 'bugs' with >> > > preserve-merges and interactive rebase. Without the --preserve-merges >> > > option, those operations works as expected. >> > > >> > > The reason, as that section explains, is that it's not possible to store >> > > the merge structure in the flat todo list. I assume this means git >> > > internally remembers where the merge commit was, and then restores it >> > > while rebasing. >> > > >> > > Changing the order, or dropping commits might then give unexpected >> > > results. >> > > >> > >> > The commit message may help as well: >> > >> > rebase -i -p: document shortcomings >> > >> > The rebase --preserve-merges facility presents a list of commits >> > in its instruction sheet and uses a separate table to keep >> > track of their parents. Unfortunately, in practice this means >> > that with -p after most attempts to rearrange patches, some >> > commits have the "wrong" parent and the resulting history is >> > rarely what the caller expected. >> > >> > Yes, it would be nice to fix that. But first, add a warning to the >> > manual to help the uninitiated understand what is going on. >> >> Thanks, but all of this still talks about the issues in very generic >> terms ("most attempts to rearrange patches"). I'm interested in more >> details as to exactly what kind of attempts do or don't work. In >> particular, I'm interested in fixup/squash commands (without reordering >> anything else), or dropping (non-merge) commits. >> >> I could of course experiment with these and try to find out myself, but >> I was hoping someone would just know the answer off the top of their >> head, saving me some time. > > The fundamental problem here is the underlying design of bolting on the > "recreate a merge" functionality onto the "pick" command. > > That is, if you try to rebase non-linear commit history, it will still > generate a linear list of "pick <commit-name>" lines, as if it were > linear, except that it will include the merge commits, too. Which on a more fundamental design level would be ok. (C.f. your shell history is a linear list of git commands, but it deals just fine with non linear DAGSs) > > It then will try to guess what you want to do by recording which commit > was rewritten as which commit. And when it encounters a "pick" with a > merge commit, it will try to merge the *rewritten* commit. Instead of guessing we'd need to differentiate between "pick" and "pickmerge", whereas the later describes creating commits with more than one parent (i.e. the prior pick line). I could imagine the "pickmerge" to list all additional parents (The first parent being the previously picked commit) via symbolic naming: pick 1234affe implement foo pickmerge 3456feed origin/js/new-feature-1 # Merge origin/js/new-feature-1 pick 45678ead implement feature-2 The "pickmerge" would have first the merge tips, and then the old subject line after a # character. > > In other words, the design does not allow for changing the tip of any > merged branch. Not reordering, not dropping. I see how the current design is problematic as there is no argument possible that allows the user to correct the wrong guess. > > And I do not think that there is a way to fix that design. That is why I > came up with the Git garden shears (see the link I sent elsewhere in this > thread). I'll look into that. Thanks, Stefan