如何解决对上游分支的强制推送?

问题描述

我有一个功能分支 branchX,它使用 some-remote/base-branch 作为其上游分支。我刚刚发现 some-remote/base-branch 的历史被强制推送改写了。涉及哪些问题,我该如何解决

解决方法

这带来的最大问题是,您应该摆脱从旧的上游分支重写的修订,这样当您推送您的功能分支时,它们就不再存在了。 >

如果您尝试在新分支的顶部重新设置分支(例如 git checkout branchX; git fetch some-remote; git rebase some-remote/base-branch),git 不仅会重新设置功能分支的修订版本而且搬出新的重写分支......这是一个不行。如果合并也是一样。因此,简单的 git pull(合并或变基)不会让您摆脱困境……实际上,您很可能更深入地陷入困境。

如果您决定保持它们就好像什么都没发生,您将进入上游分支的历史记录,已经从中删除的修订, 很有可能,没有必要保留它们(因为....为什么首先要重写分支的历史记录,对吗?如果重写了,那些旧的修订版不会再也见不到了)。

这似乎是一件大事,但坦率地说,摆脱困境并不难。诀窍是将您的功能分支的 修订版移动到新的重写分支之上,而将旧分支留在后面。所以,这就是过程,假设你的特征的分支是一条没有合并的直线:

承诺

您的功能分支的历史记录中查找(例如,使用 git loggitk 或任何其他必要的方式),旧版本的最新修订 在您的功能分支中的上游分支。假设您获得了该修订的 ID,我们将其命名为 old-base-rev

从远程获取以获取上游分支的新重写历史记录。

git fetch some-remote # adjust to the name of your remote,of course

转弯

这就是魔法发生的地方:

git rebase --onto some-remote/base-branch old-base-rev branchX

这种方式 git 只会重新调整实际上构成功能分支本身工作的修订,而不是旧的上游分支。

声望

就是这样。您可以自由地继续在您的分支上工作,就好像什么都没发生一样。

其他可能性

如果您正在处理一个直的功能分支(它合并了上游分支而不是重新设置了它的基础),您可以使用我提供的相同配方,但是,如果您合并上游分支时必须解决冲突,这会很棘手。如果您想避免再次处理冲突,也许您可​​以尝试的最好方法是将您对功能分支的更改放入单个修订版中,然后尝试魔术。在您的功能分支中找到 old 基础分支的最后一个 ID 之后:

git reset --soft old-base-rev
git commit -m "Single revision for feature X"

现在您的所有更改都已折叠到 old-base-rev 之上的单个修订版中。然后,您可以按照获取/rebase 步骤的方法进行操作。

git fetch some-remote
git rebase --onto some-remote/base-branch old-base-rev branchX