How to rebase only the commits after the latest merge?

旧巷老猫 提交于 2019-12-03 21:18:50

You start from:

     (1)
x--x--x--x--x--x--x         master
       \     \
        y--y--Y--y--y       dev
          (2)(3)   (4)

Do a git rebase --onto:

git branch dev1 Y^
git rebase --onto master Y^ dev

Y^ references the first parent of the merge commit Y: here 'y', and not 'x'.
See "Ancestry References":

The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in.

You would end up with:

     (1)
x--x--x--x--x--x--x             master
       \           \
        y--y        Y'--y'--y'  dev
          (2)      (5)
        (dev1)

That would split your initial dev branch in two, and apply only the last dev commits on top of master, while keeping the first dev commits unchanged, now referenced by the branch dev1.

You can try a:

git rebase -p --onto master `Y^` dev

to see if that preserve the relationship between between y (that is Y^) and the newly rebased Y'. But I doubt that is possible.

-p is for --preserve-merge.

Using my and VonC's answers made more automate-able solution:

git checkout -b tmp Y
git merge master 
git reset --soft HEAD^^ 
git rev-parse master > .git/MERGE_HEAD 
git commit -C Y
git checkout -
git rebase --onto tmp Y
git branch -d tmp

Y - is the merge commit to be extended.

And it works like this:

x--x--x--x--x--x--x         master
       \     \
        y--y--Y--y--y       dev

x--x--x--x--x--x--x         master
      |      \
       \      Y             tmp
        \    / \
         y--y   y--y        dev

x--x--x--x--x--x--x         master
      |      \     \
       \      Y-----Y'      tmp
        \    / \
         y--y   y--y        dev

x--x--x--x--x--x--x         master
      |            \
      |      -------Y'      tmp
       \    /
        y--y--Y--y--y       dev

x--x--x--x--x--x--x         master
      |            \
      |      -------Y'      tmp
       \    /        \
        y--y          y--y  dev

x--x--x--x--x--x--x           master
       \           \
        y--y--------Y'--y--y  dev

I end up doing the following:

git rebase -i -p Y^

In the file add the following line after line with the merge (presumably after the first line):

exec sh -c "git merge master; git reset --soft HEAD^^; git rev-parse master > .git/MERGE_HEAD; git commit -C `git rev-parse HEAD`"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!