Rebasing a Git merge commit

Rebasing a Git merge commit

问题

 

评论

TL;DR: git rebase --preserve-merges origin/master
– Ilia K.
Mar 1 '12 at 7:38

 

Warning: starting with Git 2.18 (Q2 2018, 5 years later), git --rebase-merges will ultimately replace the old git --preserve-merges. See What exactly does Git's “rebase --preserve-merges” do (and why?)
– VonC
May 27 '18 at 19:30
 
 
 
回答1

There are two options here.

One is to do an interactive rebase and edit the merge commit, redo the merge manually and continue the rebase.

Another is to use the --rebase-merges option on git rebase, which is described as follows from the manual:

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. Any resolved merge conflicts or manual amendments in these merge commits will have to be resolved/re-applied manually."

 
 回答2

Ok, it's an old question and it already has an accepted answer by @siride, but that answer wasn't enough in my case, as --preserve-merges forces you to resolve all conflicts a second time. My solution is based on the idea by @Tobi B but with exact step-by-step commands

We'll start in the same state found in the original question:

*   8101fe3 Merge branch 'topic'  [HEAD -> master]
|\  
| * b62cae6 2                     [topic]
| |
| | * f5a7ca8 5                   [origin/master]
| | * e7affba 4
| |/  
|/|   
* | eb3b733 3
|/  
* 38abeae 1

Note that we have 2 commits ahead of master, so cherry-picking won't work.

  1. First of all, let's create the correct history:

     git checkout -b correct-history # create new branch to save master for future
     git rebase --strategy=ours --preserve-merges origin/master
    

    We use --preserve-merges to save our merge commit in history. We use --strategy=ours to ignore all merge conflicts as we don't care about what contents will be in that merged commit, we only need a nice history.

    The history will look like this (ignoring master):

     *   51984c7 Merge branch 'topic'  [HEAD -> correct-history]
     |\  
     | * b62cae6 2                     [topic]
     * | f5a7ca8 5                     [origin/master]
     * | e7affba 4
     * | eb3b733 3
     |/  
     * 38abeae 1
    
  2. Let's get the correct index now.

     git checkout master # return to our master branch
     git merge origin/master # merge origin/master on top of our master
    

    We may get some additional merge conflicts here, but that would only be conflicts from files changed between 8101fe3 and f5a7ca8, it doesn't include already resolved conflicts from topic

    History will looks like this (ignoring correct-history):

     *   94f1484 Merge branch 'origin/master'  [HEAD -> master]
     |\  
     * | f5a7ca8 5                   [origin/master]
     * | e7affba 4
     | *   8101fe3 Merge branch 'topic'
     | |\  
     | | * b62cae6 2                     [topic]
     |/ /
     * / eb3b733 3
     |/  
     * 38abeae 1
    
  3. The last stage is to combine our branch with correct history and branch with correct index

     git reset --soft correct-history
     git commit --amend
    

    We use reset --soft to reset our branch (and history) to correct-history, but leave index and working tree as is. Then we use commit --amend to rewrite our merge commit, that used to have the incorrect index, with our good index from master.

    In the end we will have this state (note another id of top commit):

     *   13e6d03 Merge branch 'topic'  [HEAD -> master]
     |\  
     | * b62cae6 2                     [topic]
     * | f5a7ca8 5                     [origin/master]
     * | e7affba 4
     * | eb3b733 3
     |/  
     * 38abeae 1
    
 
 
 
 
 
作者:Chuck Lu    GitHub    
posted @   ChuckLu  阅读(135)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2020-12-14 Regex plus vs star difference?
2017-12-14 remote debug
2017-12-14 客户端通过wcf来启动或者停止服务器上的windows service
点击右上角即可分享
微信分享提示