Git,撤消在 rebase 上的合并提交

Git, undo merge commit on rebase

我有一段历史,大致如下

  * (TOPIC) topic 3
  |
| * merge master onto topic
|/|
* | master 3
| * topic 2
* | master 2
| | 
| * topic 1
|/
* master 1
|

即上游分支一次合并到主题中。现在,我想以交互方式将此主题分支 重新设置在同一基础 上,但撤消合并(合并提交本身以及合并引入的来自 master 的所有提交)。这怎么可能?

让我们为绘图中描绘的提交使用有效标识符:

  * topic3          (TOPIC) topic 3
  |
| * topic2merge     merge master onto topic
|/|
* | master3
| * topic2
* | master2
| | 
| * topic1
|/
* master1
|

如果你想删除合并提交(使 topic2 成为 merge master onto topic 之后第一个提交的唯一父级)你需要 运行 以下 git rebase 命令:

git rebase --onto topic2 topic2merge topic3

如果当前分支已经是topic3,你可以从上面的命令中省略topic3(如果它存在,git rebase做的第一件事就是结帐,如果它已经不是当前分支了)。

此操作后,图形如下所示:

| * topic3      <-- (TOPIC) topic 3
| |
* | master3
| * topic2
* | master2
| | 
| * topic1
|/
* master1
|

topic2mergetopic3 之间(包括它们)的提交仍然存在于存储库中,但它们不再可见。如果它们可以到达,它们仍然可见,如果有分支指向它们,就会发生这种情况。甚至远程分支。

如果您已经将 topic3 推送到远程仓库,您必须 运行 git push -f origin topic3(将 origin 替换为您遥控器的名称)并通知您的同事您已经更改了历史记录。他们需要知道这一点;在他们的存储库上 topic3 的历史记录中仍然有 topic2merge 并且您所做的更改代表了他们的存储库不会自动采用的替代历史记录行。他们必须使用 git reset --hardgit rebasegit cherry-pick 才能跟上。

您可以使用命令

git rebase -i --onto master1 master topic

这将获取 topic 中但不在 master 中的所有非合并提交(即 topic1、topic2、topic3),并将它们应用到 master1 提交之上.