On 28/02/2018 03:12, Igor Djordjevic wrote: > > Would additional step as suggested in [1] (using R1 and R2 to "catch" > interactive rebase additions/amendments/drops, on top of U1' and > U2'), make more sense (or provide an additional clue, at least)? > > [1] https://public-inbox.org/git/8829c395-fb84-2db0-9288-f7b28fa0d0d1@xxxxxxxxx/ Heh, no sleeping tonight :P Anyway, from (yet another) ad hoc test, additional step mentioned in [1] above seems to handle this case, too (merge with `-s ours` dropping B* patches, plus B1 cherry-picked between X1..X2): On 28/02/2018 00:27, Johannes Schindelin wrote: > > - One of the promises was that the new way would also handle merge > strategies other than recursive. What would happen, for example, if M > was generated using `-s ours` (read: dropping the B* patches' changes) > and if B1 had been cherry-picked into the history between X1..X2? > > Reverting R would obviously revert those B1 changes, even if B1' would > obviously not even be part of the rebased history! > > Yes, I agree that this `-s ours` example is quite concocted, but the point > of this example is not how plausible it is, but how easy it is to come up > with a scenario where this design to "rebase merge commits" results in > very, very unwanted behavior. And not just that - it worked with additional interactive rebase adding, amending and removing commits, on top of all this still preserving original `-s ours` merge commit evil-merge amendment, too, all as expected (or so it seems) :P Again, for the brave ones, here`s another messy test script (not tightly related to the last discussed diagrams, but based on my original "demonstration" script[2])... Hopefully I get to make a proper (and sane) sample soon... if not missing something here in the first place ;) Regards, Buga [2] https://public-inbox.org/git/bbe64321-4d3a-d3fe-8bb9-58b600fabf35@xxxxxxxxx/ -- 8< -- #!/bin/sh # rm -rf ./.git # rm -f ./test.txt git init touch ./test.txt git add -- test.txt for i in {1..20} do echo A$i >>test.txt git commit -am "A$i" done git checkout -b b1 sed -i '3iB11' test.txt git commit -am "B11" sed -i '7iB12' test.txt git commit -am "B12" git checkout -b b2 HEAD^ sed -i '16iB21' test.txt git commit -am "B21" sed -i '18iB22' test.txt git commit -am "B22" git checkout -b merge b1 git merge -s ours --no-commit b2 sed -i '12iX' test.txt # amend merge commit git commit -am "M" git tag original-merge git checkout master git cherry-pick b2 for i in {1..5} do j=`expr "$i" + 20` sed -i "${i}iA${j}" test.txt git commit -am "A$j" done # simple/naive demonstration of proposed merge rebasing logic # using described "Trivial Merge" (TM, or "Angel Merge"), # preserving merge commit manual amendments, but still respecting # interactively rebased added/modified/dropped commits :) # read -p "Press enter to continue" git checkout b1 git cherry-pick -m1 original-merge && git tag U1 git reset --hard HEAD^^ # drop U1 and last b1 commit sed -i '/B11/c\B1111' test.txt git commit -a --amend --no-edit git rebase master git cherry-pick U1 && git tag U1-prime # read -p "Press enter to continue" git checkout b2 git cherry-pick -m2 original-merge && git tag U2 git reset --hard HEAD^ # drop U2 git rebase master sed -i '20iBX' test.txt git commit -am "BX" # add new commit git cherry-pick U2 && git tag U2-prime git diff U1 U1-prime | git apply --3way && git commit -m "U2-second" && git tag U2-second git checkout b1 git diff U2 U2-prime | git apply --3way && git commit -m "U1-second" && git tag U1-second # read -p "Press enter to continue" git branch -f merge b1 git checkout merge git merge b2 --no-commit git commit -a --reuse-message original-merge git tag angel-merge # read -p "Press enter to continue" git reset --hard b1^ git read-tree --reset angel-merge git update-ref refs/heads/merge "$(git show -s --format=%B original-merge | git commit-tree "$(git write-tree)" -p "$(git rev-parse b1^^)" -p "$(git rev-parse b2^^)")" git tag -f angel-merge git checkout angel-merge . git branch -f b1 b1^^ git branch -f b2 b2^^ # show resulting graph echo git log --all --decorate --oneline --graph # comparison between original merge and rebased merge, # showing merge commit amendment "X" being preserved during rebase # (not shown in diff) echo echo 'diff original-merge angel-merge:' git diff original-merge angel-merge