Git:在合并分支上工作,之后未合并

Git: Work on merged branch, which was unmerged afterwards

我遇到了以下问题: 我在分支机构 A 工作。 分支 A 已合并到 Master 分支,目前一切顺利。

一段时间后,客户决定撤消在 Master 分支上的分支 A 中完成的更改,因为它必须更新。

因此 Master 分支中的历史记录如下:

Some stuff
Some other stuff
Some stuff, where the merge of Branch A was reverted
Some other stuff
Some other stuff
Branch A was merged into master
The commit of Branch A (Branch A contains one Commit)

我想对分支 A 进行变基,所以我想要这样的东西:

The commit of Branch A (From here I want to continue working)
Some stuff
Some other stuff
Some stuff, where the merge of Branch A was reverted
Some other stuff
Some other stuff
Branch A was merged into master
The commit of Branch A (Branch A contains one Commit)

请注意,我不想更改我的远程主机的历史记录,我需要分支 A 的提交以我的主机的最后一次提交为基础。然后我想把我更新后的Branch A再次推送到Master。

现在我想继续在分支 A 上工作,但首先我想在当前主分支上对分支 A 进行变基,以获得最新状态。

现在的问题是:当我将我的分支 A 变基到 master 时,git 似乎删除了我在分支 A 中所做的更改。我认为这是因为 Master 分支中的合并反向。所以:Git 看到,分支 A 在 master 分支中被删除,所以当我在 master 上重新设置分支 A 时,删除也会完成。

我不想将我在 Branch A 更改的文件一个接一个地复制到另一个 Branch,这是从 master 签出的。我认为有更好的解决方案,有什么建议吗?

嗯,这有点棘手。由于 BranchAHEAD 已经是 master 的一部分,因此 git 认为 master 中的代码比 BranchA 更新。在这种情况下,如果你们重置 master 分支中的更改而不是通过显式提交还原它们会更好。

以下所有选项都涉及重写历史,因此请先在某个临时分支中尝试它们。

一种选择是使用 rebase --onto 更改主分支,以便删除合并和还原提交。

git rebase --onto <commit_id_before_merge_commit> <revert_merge_commit_id> master

其次是更改 BranchA 中的提交哈希,这样 git 就不会像在 master 中那样识别它们。

git checkout BranchA
git reset HEAD^n # n is the number of commits that are exclusive to branchA
git add -u # Add all the files. Make sure to add newly created ones.
git commit -m 'some message'
git rebase master # should work now

第三,您还可以使用交互式变基来更改 BranchA

中的提交 ID
git rebase -i <first_exclusive_initial_commit_id_of_branchA>

如果您使用 git checkout branch-a && git rebase -i master,您将在文本编辑器中获得一个提交列表,每个提交前面都有 pick 命令。您可以将其更改为几个选项之一,所有这些选项都在给定的文本中进行了解释。例如,您可以 skip 恢复提交,这些更改将不会被恢复。

另一种可能的解决方案是重新设置基线,因为您已经 git revert 恢复了 branch-a.

合并的提交

由于您不想触及 master 的历史记录,因此您需要将更改重新应用到 master 的顶部,忽略它们已经应用和还原的事实。根据还原提交的确切性质,我们称之为 <revert>,我看到了两种实现此目的的方法:

  1. 如果 <revert> 撤消了您的更改,那么您可以再次还原它以获得重新应用您的更改的提交(想想 --x == x).

  2. 如果还原提交不是纯粹的,我会这样处理这种情况:

    • 使用 git format-patch.

    • 为您的分支创建补丁序列
    • 将此补丁序列应用到 git am 的母版。

    重点是,git am 与历史无关:它只查看当前提交的状态并对其应用补丁。