Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid git rebase killing merge commits?

Given the following git history:

    C-I    origin/master    / A-B-F-G-H  master  \   /   D-E      branch-b 

I want to rebase my local master branch on top of origin/master, but I want to preserve the merge commit G. When I tried simply doing a git rebase origin/master while at master it squashed D..E as G and committed that with the commit message of E, so the history that there was a merge was lost. Is there some way of preserving this merge while still getting the rebase? For clarity, my intended result is:

A-B-C-I-F-G-H  master  \       /   D-----E      branch-b 
like image 454
Matthew Scharley Avatar asked Jun 02 '11 23:06

Matthew Scharley


People also ask

Does rebase ignore merge commits?

By default, a rebase will simply drop merge commits from the todo list, and put the rebased commits into a single, linear branch. With --rebase-merges, the rebase will instead try to preserve the branching structure within the commits that are to be rebased, by recreating the merge commits.

Does rebase preserving merge commits?

Merge-preserving rebase is willing to replay (some) merge commits, whereas normal rebase completely ignores merge commits.

How do I stop rebase abortion?

You can run git rebase --abort to completely undo the rebase. Git will return you to your branch's state as it was before git rebase was called. You can run git rebase --skip to completely skip the commit.


2 Answers

Add --preserve-merges to your rebase command. In case there were conflict resolutions in your merge, add 'recursive theirs' strategy as a parameter as well.

EDIT: --preserve-merges is now deprecated, use --rebase-merges instead

like image 104
Adam Dymitruk Avatar answered Oct 02 '22 18:10

Adam Dymitruk


This isn't going to be very pretty but I think you can do it.

Rebase F onto the origin/master as your new master branch:

git checkout F git checkout -b new_master git rebase origin/master 

Merge branch-b into your new branch:

git merge branch-b 

Cherry pick the remaining H commit onto your new master branch:

git cherry-pick master 

Delete your old master branch:

git branch -D master 

Unfortunately you will also have to do the merge again (hopefully it doesn't take any manual merging).

I didn't actually try this out, so I would make a backup of the repository first, but I am pretty confident that you will get what you want. I also suggest opening up gitk --all and refreshing the tree with "F5" after each command so you can see what is changing.

Someone else should still post if they know of a more elegant way to do it.

like image 44
drewag Avatar answered Oct 02 '22 16:10

drewag