Jörg Sommer <joerg@xxxxxxxxxxxx> writes: > Me too, but I think it's not possible to do what I want with -p. -p > misses a definition of the (new) parent of a commit. It tries to preserve > all commits from all branches. But going through the _list_ of commands > couldn't preserve this structure. > > o--A--B > \ \ > C--D--M--E > > How should the graph look like after these commands: > > pick A > pick C > squash E > # pick D > pick B > pick M I am beginning to suspect that the root cause of this is that the todo language is not expressive enough to reproduce a merge _and_ allow end user editing. Let's step back a bit. If you have this history: o---o---o---o---o---Z / X---Y---A---B \ \ C---D---M---E and you want to transplant the history between X..E on top of Z, from the command line you would say: $ git rebase --interactive -p --onto Z X E First let's think what you would do if you want to do this by hand. The sequence would be: $ git checkout Z^0 ;# detach at Z $ git cherry-pick Y $ git tag new-Y ;# remember it $ git cherry-pick A $ git cherry-pick B $ git tag new-B ;# remember it $ git checkout new-Y $ git cherry-pick C $ git cherry-pick D $ git merge new-B ;# this reproduces M $ git cherry-pick E $ git branch -f $the_branch && git checkout $the_branch Now how does the todo file before you edit look like? pick Y pick A pick B pick C pick D pick M pick E The todo file expects the initial detaching and the final switching back outside of its control, so it is Ok that the first "checkout Z^0" and the last "branch && checkout" do not appear, but it should be able to express the remainder and let you tweak. Is it expressive enough to do so? Most of the "pick" from the above list literally translate to the "cherry-pick", and if you change any of them to "edit", that is "cherry-pick --no-edit" followed by a return of control to you with insn to "rebase --continue" to resume. There appears nothing magical. Not really. There already are two gotchas even without talking about end-user editing. First, "pick M" is not "cherry-pick M". You do not want to end up with merging an old parent before rewriting. It has to be something like "merge rewritten-Y". Second, before you start picking C, if you want to preserve merges, you have to switch to rewritten Y. The original sequence left in todo does not have that information to begin with. We need, before the "pick C", to say the equivalent of "git checkout new-Y" in the manual sequence illustrated above. The lack of "checkout new-Y" is perfectly fine if rebase is meant to linearlize the history, but if you want to preserve the shape of the history, you would need to give a clue that the sequence that begins with the "pick C" starts from somewhere else. You also need to make sure that "pick M" moved elsewhere still merges the tips of two forked histories. Moving "pick M" before "pick C" or "pick A" would not make much sense. So you would need some kind of "barrier" that says "do not move this 'pick M' beyond this point". Perhaps we can make it clearer by introducing a few more primitives to the todo language: mark, reset and merge. The above illustrated history would then become: pick Y mark #0 pick A pick B mark #1 reset #0 pick C pick D mark #2 merge #1 #2 pick E You can change any of the "pick" to "edit, or drop it, and you can reorder "pick" in a sequence of "pick", but you cannot change "mark", "reset", "merge", or move "pick" across insn that was not originally "pick". -- 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