Re: [RFC] Rebasing merges: a jorney to the ultimate solution (Road Clear)
- From
- Igor Djordjevic <igor.d.djordjevic@gmail.com>
- Date
- Feb 28, 2018, 04:35 UTC
- Message-ID
- <b4367bca-79a0-879b-9503-ed4e667d8a64@gmail.com>
- In-Reply-To
- <3b562b51-2f1a-48f6-d6b4-8e0fbddd3a40@gmail.com>
On 28/02/2018 03:12, Igor Djordjevic wrote:
Show 6 quoted lines
> > 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@gmail.com/
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:
Show 13 quoted lines
> > - 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@gmail.com/
-- 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"
donegit 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