为了重播请求,如何使用rebase而不是merge来重播历史记录?

问题描述 投票:0回答:2

同事是git的新手。他从事某个功能分支已经有一段时间了,现在已经创建了一个PR(如果重要的话,请使用Azure DevOps)。

[不幸的是,他不知道git rebase,因此他一直使用git pull origin master进行同步,这导致了很多合并提交。 (在他的功能分支上有20个“实际”提交和9个合并提交)

现在,这很好,但是结果是PR的差异视图不仅显示了他的更改,而且还显示了同时在master上应用的所有其他更改。现在基本上不可能进行适当的代码审查,因为他的更改与所有其他更改都没有区别。

现在,我的计划是以某种方式重放他的所有更改,但是每当他进行合并时,我都会进行重新设置基准。每当在重新设置基准期间发生冲突时,在相应的合并提交的更改中进行混合就可以完美地解决该问题(理论上)。大多数合并都非常困难,因此无法手动重做,因为这项工作已经完成。

实现此目标的最佳方法是什么?

  1. 我尝试过git rebase master,但这不包括合并提交,因此必须手动完成。

  2. 我也尝试过git rebase --preserve-merges master,但是由于某些原因,这只会做基础直到最新的合并提交为止(见下文)。

[如果没有更好的选择,我将不得不做20 + 9个樱桃小菜...


交谈中的图片,情况是这样:

A---B---C- ... --D---E---F         master
 \   \      ...   \         
  G---m---H- ... --m---I---J       feature

我想要这个:

A---B---C- ... --D---E---F                                   master
                          \                          
                           G'--m'--H' ... --m'--I'--J'       feature

选项1.只会给我这个,但我想获得m(不一定是提交,但我希望以某种方式解决那些冲突):

A---B---C- ... --D---E---F                                   master
                          \                          
                           G'------H' ... ------I'--J'       feature

选项2.只会给我这个,没有太大帮助:

A---B---C- ... --D---E---F                 master
 \   \      ...   \       \         
  G---m---H- ... --m-------m'--I'--J'      feature
git merge rebase
2个回答
2
投票

Rebase无法做到这一点。它要么完全删除合并,要么re-performs合并。如果它重新执行合并,则您获得的合并提交就是实际的合并提交。在您的情况下,您需要使用-m进行等同的选择。 (我认为您想要-m 1,但请确保使用,尤其是在使用以下内容之前。)

[如果没有更好的选择,我将不得不做20 + 9个樱桃小菜...

这就是要走的路。使用git rev-list或类似的名称列出要复制的所有提交。记下其中哪些是合并。然后写一个小脚本:

git cherry-pick <hash-of-G>
git cherry-pick -m 1 <hash-of-merge#1>    # or maybe -m 2?
git cherry-pick <hash-of-H>

依此类推。一次运行一个命令,以使您知道在哪里以及何时发生故障,或者您对错误的处理有足够的把握,将其作为设置为-e的脚本运行,以免出现故障。其余的内容。


0
投票

我找到了一个非常顺利的解决方案:

  1. 让您完全处于开始进行功能时的状态

    git checkout -b replay_feature <hash-of-A>  
    
  2. 完全重做他的操作,直到完成合并:

    git cherry-pick <hash-of-G>       # redo his non-merge commit(s)
    
  3. 现在,他做了git merge master,所以我改了git rebase master

    git rebase <hash-of-B>            # back then, B was HEAD of master
    
  4. 现在,我正在重新进行基础设置,面临与他所面临的完全相同的冲突,他用m解决了该冲突。因此,为了以与他完全相同的方式解决该问题,我只是从他的合并提交中签出所有冲突的文件。

    git checkout <hash-of-merge> -- file-in-conflict.cpp    # do this for all conflicts
    # make sure everything compiles
    git add .
    git rebase --continue                                  
    
  5. 重复第3步,直到完成变基

重复步骤2至5.,直到重播他的全部作品,将所有合并替换为变基并应用他的冲突解决方案。最后,比较分支replay_featurefeature。如果一切顺利,则所有文件应相同。

git diff replay_feature feature    # should not show anything
© www.soinside.com 2019 - 2024. All rights reserved.