44

背景:我最近将一个相当大的主题分支合并到master. 几天后,我发现这个主题分支包含错误。所以我git revert -m 1 <merge-commit>编辑了它。

问题:现在我想检查主题分支并将其重新设置为当前分支,master以便我可以 1)修复错误和 2)(再次)将已修复的主题分支与 master 合并。创建新分支fixedtopic是很容易的部分,但每次我都这样做

git checkout fixedtopic
git rebase master

git 决定它不愿意重放旧的提交,因为它们已经合并到master. 相反,它只是做一个快进的变基。

问题:如何强制重放提交到fixedtopicusing rebase?我可以吗?我宁愿不使用cherry-pick,因为它有点麻烦。

额外的:

  • git reseting 合并提交它不是一个选项,因为我已经将 master 推送到上游。
  • 我宁愿不创建一个新的分支master并恢复我的回复。这样做的原因是我想使用交互式 rebase 重写一些主题分支的历史。
  • 这是该场景的 github 要点:https ://gist.github.com/JensRantil/6352495 请注意,我希望将 e8df5ec 和 ee16464 应用于master(或基于 的分支master)。
4

6 回答 6

15

实现此目的的一种方法是交互式地重新设置主题分支并在分支出 master 后重新编写第一个提交(例如git rebase -i HEAD~10,如果您在分支中有 10 个提交)。这将重写主题分支内所有提交的 sha。因此,您将能够使用git rebase master.

于 2013-08-27T12:53:05.360 回答
15

文档(git help rebase)建议“git rebase --force-rebase”就是这样做的——但是(Git 1.9.1)它没有。该文档建议“git rebase -i --no-ff”等同于该命令 - 但它不是:它确实有效。

克隆了你的要点后,命令:

  git checkout topic
  git rebase -i --no-ff --onto master 7b3af topic

产生所需的结果,新版本的“第三”和“第四”提交在 master 之上,并topic指向新版本的“第四”。在第二个命令中,SHA7b3af是“第二个”提交,即topic分支点。

于 2015-08-14T15:15:50.633 回答
12

有了git 2.22,jurglic 建议的解决方案似乎不再起作用。

让我们从状态开始,以确保我们谈论的是同一件事:

P---o---o---M---o---o---o---o---o---W---o---o---master
 \         /     \                /
  A---B---C       D (revert A-B-C)

我创建了一个带有A-B-C提交的 dev 分支,它被合并MW. A-B-Cmaster再次合并之前,我想重新定位并修复该问题。

这是我所做的:

git checkout C          (detached HEAD) 
git checkout -b redo
git rebase -i master

但在这一点上,git 只为我提供了以下内容:

noop

# Rebase A..C onto X (1 command)

这意味着它发现我正在尝试重新应用完全相同的提交并且它们已经被合并。

为了解决这个问题,jurglic 建议修改A's 提交消息,但它似乎git 2.22足够聪明,可以弄清楚并且仍然为我提供完全相同的noop. 我尝试了其他解决方案,使用--force-rebase和/或--no-ff,但我一直回到noop.

最后,我使用了一个简单的捷径,在rebase -i选择编辑器中手动输入,然后替换noop为:

pick A
pick B
pick C

或者,如果您想保存更多击键:

p A
p B
p C

这最终像一个魅力。

于 2019-12-01T08:33:29.817 回答
5

您需要使用--onto来防止 Git 表单尝试自行确定适当的未合并提交。

例如(已签出主题分支):

git rebase --onto master <id-of-branch-point>

因为<id-of-branch-point>你想要git merge-base你的主题分支和在你恢复的合并之前在 master 上的提交。

编辑

再次重新阅读您的情况,如果您将主题分支快进到您恢复合并的点,然后恢复恢复并从该点修复主题分支,可能会更好。这样,您将不会重复原始主题分支中的所有提交,而是在 master 的最终历史记录中使用新的 id。无论你做什么,你最终都会得到一个涉及“做、撤消、重做”的历史,但这种方式可能被认为是一个更干净的历史。

于 2013-08-27T10:50:23.280 回答
1

似乎最好的方法是检查一个新分支,然后通过还原 revert 来恢复以前的工作分支。

我尝试过的其他一切都过于复杂和/或不起作用。

于 2014-09-10T02:18:51.827 回答
0

对于git merge(即不是git rebase最初要求的),根据7.8 Git 工具 - 高级合并(请参阅“反转提交”部分):

解决此问题的最佳方法是取消还原原始合并,因为现在您想要引入已还原的更改,然后创建一个新的合并提交:

$ git revert ^M

<...>

$ git merge topic

重新合并还原合并后的历史 图 142. 重新合并恢复的合并后的历史记录

于 2019-05-21T14:34:17.473 回答