git 变基还原合并分支

xbp102n0  于 2023-02-28  发布在  Git
关注(0)|答案(7)|浏览(246)

**背景:**我最近合并了一个相当大的主题分支到master。几天后我发现这个主题分支包含bug。所以我修改了它。
**问题:**现在我想 checkout 主题分支,并根据当前的master重定基,这样我就可以1)修复bug,2)(再次)将修复的主题分支与master合并。创建新分支,fixedtopic是容易的部分,但每次我都这样做

git checkout fixedtopic
git rebase master

git决定不重新执行旧的提交,因为它们已经合并到master中了,而只是执行一个快进的变基。

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

  • 合并提交不是一个选项,因为我已经将主进程推向上游。
  • 我不想在master上创建一个新的分支并恢复我的revert,原因是我想使用交互式rebase重写一些topic分支的历史。
  • 下面是这个场景的一个要点:https://gist.github.com/JensRantil/6352495请注意,我希望e8df5ec和ee16464应用到master(或基于master的分支)。
qlvxas9a

qlvxas9a1#

文档(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

产生期望的结果,其中新版本的“第三”和“第四”提交在主提交之上,并且topic指向新版本的“第四”提交。在第二个命令中,SHAx 1 m1n1x是“第二”提交,即topic从其分支的点。

yshpjwxd

yshpjwxd2#

实现这一点的一种方法是交互式地重定topic分支的基,并重写分支出master之后的第一个提交(例如,如果分支中有10个提交,则重写git rebase -i HEAD~10)。这将重写topic分支中所有提交的sha。因此,您可以使用git rebase master的常规重定基方法。

mv1qrgav

mv1qrgav3#

对于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分支,它被合并到M中,但我们立即注意到有一个错误,所以它被还原到W中。我想在master上重定A-B-C的基,并在再次合并之前修复这个问题。
我是这么做的:

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

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

noop

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

这意味着它发现我试图重新应用完全相同的提交,而它们已经被合并了。
为了解决这个问题,jurglic曾建议修改A的提交消息,但似乎git 2.22足够聪明,能够解决这个问题,并且仍然为我提供完全相同的noop。我尝试了其他解决方案,使用--force-rebase和/或--no-ff,但我一直回到noop
最后,我使用了一个简单的快捷方式,在rebase -i选择编辑器中手动输入,并将noop替换为:

pick A
pick B
pick C

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

p A
p B
p C

这一招终于奏效了。

7cjasjjr

7cjasjjr4#

你需要使用--onto来防止Git试图自己决定合适的未合并提交。
例如(主题分支已 checkout ):

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

对于<id-of-branch-point>,你需要你的主题分支的git merge-base,以及在你恢复的合并之前 * master上的提交。

    • 编辑**

再次重新阅读你的情况,如果你把主题分支快进到你恢复合并的点,然后恢复合并并从那个点修复主题分支,这 * 可能 * 会更好。这样你就不会得到原始主题分支中所有提交的重复,而是在master的最终历史记录中有新的id。无论你做什么,你都会得到一个包含"do,撤销,重做",但是这种方式 * 可能 * 被认为是更干净的历史。

xzabzqsa

xzabzqsa5#

看起来最有效的方法是 checkout 一个新分支,然后通过revert命令恢复以前的分支。
我尝试过的其他方法都过于复杂和/或不起作用。

798qvoo8

798qvoo86#

对于git merge(即不是最初要求的git rebase),根据7.8 Git工具-高级合并(参见“撤销提交”部分):
解决这个问题的最好方法是取消还原原来的合并,因为现在你想引入还原出来的更改,* 然后 * 创建一个新的合并提交:
$ git revert ^M
<...>
$ git merge topic
x1c 0d1x图142.重新合并恢复的合并后的历史记录

niwlg2el

niwlg2el7#

什么对我来说最有效,隐藏我的特性分支的变化,并将它们应用到main的新分支,并解决那里的冲突(如果有的话)。

git checkout my-feature-branch
git reset --soft <commit-on-main-that-the-feature-branch-was-branched-off>
git stash
git checkout main
git checkout -b my-feature-branch-2
git stash pop

这是一个更安全的方法,它更不可能弄乱任何已有的分支,如果在特性分支恢复后其他PR已经合并到main中,它还允许你解决新分支中的冲突。

相关问题