Git 将分支变基到旧提交

Git rebase branch onto older commit

注意:这种情况是如何形成的更像是一个故事,与 IMO 无关。

给定以下 git 提交图,从最旧的开始,全部推送到原点

          start
            |
         breaking
       /          \
fix #0             work
    |               |
fix #1(master)     morework(issue-fix)

我需要将我的分支(问题修复)移动到基于开始,而不是破坏,即将它变成

          start
       /         \
breaking            |
    |               |
fix #0             work
    |               |
fix #1(master)     morework(issue-fix)

breaking 中的更改与问题修复(项目的不同部分)无关,但它们会导致该分支的 CI 失败,因为测试也涵盖了项目的该部分。

我原以为 rebase 会起作用,但是在检查了更多工作之后,在 SourceTree 中尝试它什么也没做,手动 运行 git rebase start 只打印 Current branch issue-fix is up to date

有没有一种简洁有效的方法来做到这一点?如果不需要,我不想创建一个新分支并手动移动所有内容。

编辑:此外,问题修复已被拉入另一个分支,因此也在那里引入了错误的提交。相同的流程会在那里工作,还是会在问题修复时中断该分支?

您应该使用交互式变基从您的 issue-fix 分支中删除 breaking 提交。

在你的情况下,你应该结帐到 issue-fix 分支并执行:

git rebase -i HEAD~3

然后当编辑器打开时,您应该能够选择要保留和删除的提交:

drop 2dsafa ... will delete the commit you want to get rid of
pick sdfsadf .. will leave this commit
pick dfsa4sdc .. will leave this commit

如果你的 issue-fix 分支已经被合并到其他处于损坏状态的分支中,那么事情就变得有点复杂了。

在这种情况下,我建议使用交互式变基来摆脱来自其他分支的 issue-fix 提交。之后,我会将来自其他分支的提交重新设置在 issue-fix.

之上
git rebase --onto start work^ issue-fix

它尝试将提交从 work(包括)移动到 issue-fix 的尖端到新的基础 start

如果您想跳过或压缩一些提交,请使用 -i 的交互模式。交互式页面将向您展示如何操作。

如果你想保留合并提交,你可以添加 -p。要保留空提交,请使用 --keep-empty.

您可能还有一些问题中没有提到的其他需求。但很可能您可以在 git rebase.

的手册中找到合适的选项

您需要 运行 为此进行交互式变基。

在分支 issue-fix 运行: git rebase --interactive start

这应该pop-up编辑:

pick breaking <commit message>
pick work <commit message>
pick morework <commit message>

您应该将第一行的 "pick" 更改为 "drop" - 即,您想要从您的分支中删除 breaking 提交并将其重新设置为 [=14] 的顶部=]. 保存并关闭编辑器。 运行 git log 查看结果。

一如既往,当变基更改提交哈希时要小心,即即使提交 workmorework 看起来 相同,它们的 parents 会发生变化,导致它们各自的提交哈希值发生变化。 如果 issue-fix 是共享分支,这有潜在的危险。

如果您不确定是否有人已经拉取了您的 issue-fix 分支,我会选择 git revert breaking。 这是一个安全的选择,不会弄乱你的分支历史(它只是添加另一个提交 "cancels out" breaking)。