git - 修改使用 merge 以使用 rebases 的 git 主题分支的历史记录

标签 git git-merge git-rebase

我们的 git 开发工作流程是主题分支不断地基于最新的 master 直到它们被 merge 。

但是,一位新开发人员创建了主题分支,他在其中将 master merge 到他的主题分支中,以使它们保持最新。

    A---B---C---D---E topic
   /       /   /
  F---G---H---I master

虽然将这个主题分支 merge 到 master 是完全正确的,但它会导致一个非常困惑的历史。我想将这些主题分支转换成一个干净的线性 rebased 历史,它可以通过单个 --no-ff merge 提交干净地 merge 到 master 中,即:

                A'---B'---E' topic
               /
  F---G---H---I master

理想情况下,会有一些 git-fu 允许我进行 rebase ,按原样获取主题分支上的提交,同时自动应用主题 merge 提交中已有的 merge 冲突解决信息,例如 C和 D.

我知道我可以简单地应用“git diff master..topic”的补丁,然后使用 rebase 向后工作并手动将单个补丁拆分为单独的提交,但是有没有更简单、更优雅的方法?

我试过直接 git rebasegit rebase -p 命令,但没有成功。

最佳答案

我发现以下过程似乎运行良好,但并不完美。可能需要一些小的冲突解决方案——见下文。

  1. 通过从 master 进行最终 merge (如果尚未完成),确保主题分支与最新的 master 保持同步:

    git checkout topic
    git merge master
    
  2. 通过排除 merge 来简化主题分支的历史:

    git log --no-merges
    
  3. 根据上面的日志,判断分支点(第一个topic分支commit之前master上的commit,应该是commit F)。

  4. 将主题分支 rebase 到 master,忽略 merge (这是默认设置,即不使用--preserve-merges/- p 选项),解决任何冲突。

    git checkout master
    git rebase --onto HEAD F topic
    

    我发现在 rebase 期间,经常会发生冲突,文件处于冲突的“已修改”状态,但它不包含冲突标记,所以一个简单的 git addgit rebase --continue 足以解决冲突并继续。我相信 git 使用以前的解决方案来解决冲突。

    此外,在一些更复杂的分支中,将需要多个 git rebase --onto HEAD ... 命令,或者可以使用 git cherry-pick挑选出个人提交。只需完成步骤 #2 中给出的日志,将范围 rebase 到 HEAD 和/或可能根据需要挑选个别提交。

  5. 当前的 HEAD 现在应该代表 rebased 主题分支。通过检查差异结果是否没有输出来验证结果是否与原始主题分支匹配:

    git diff topic..HEAD
    
  6. 将 HEAD 命名为 rebase 主题分支名称:

    git checkout -b rebased-topic
    

关于git - 修改使用 merge 以使用 rebases 的 git 主题分支的历史记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11114309/

相关文章:

git - 被遗忘的 rebase interactive - git

eclipse - 如何阻止 Windows 上的 eclipse+git 破坏文件权限?

git - Git 是否支持仅追加文件的自动 merge 冲突解决?

git - merge 冲突错误,当提到的文件没有变化时

git: merge 两个分支:什么方向?

git - 如何将 git merge 转换为 rebase

git - 更聪明的 rebase 避免冗余工作?

android - Git - Android Studio 不再允许我提交更改并推送到 GitHub

javascript - 如何创建可重用的 Durandal 小部件

git status 将 "\n\n"显示为未跟踪文件