合并最后一个共同祖先受 rebase 影响的分支

Merging branches whose last common ancestor was affected by rebase

我有一个 master 分支和一个 topic 分支,它们在某个“最后的共同祖先”提交时与 master 分道扬镳。

我使用 git rebase 在我的 master 分支上重写了历史记录,但忘记了,这包括与我的 topic 分支“最后共同祖先”的提交。换句话说,如果我现在 git log master 分支,它不再列出 topic 的“最后共同祖先”提交。

我假设“最后的共同祖先”提交还没有被垃圾收集,因为它仍然被 topic 分支引用。但它不再是 master 分支的一部分。

如果我现在尝试将 topicmaster 合并,会发生什么?

我建议您使用 --onto 标志将主题重新建立在新母版之上。您必须指定 topic 与 master 的分歧点。找到“最后的共同祖先”,我称之为abcd。现在这样做:

git rebase --onto master abcd

编辑:刚刚意识到你说你找不到那个提交。这很奇怪。尝试转到 topic 上的最新提交,然后跟随父项直到找到该提交。它必须在某个地方。尝试使用 git rev-list --parents topic

对于这类事情,我发现 绘制 提交很有帮助。当然,由于您无法找到确切的提交,您将不得不绘制一些近似值 — 但也许这会帮助您找到正确的提交。

I have a master branch and a topic branch which diverged from master at some "last common ancestor" commit.

所以,让我们把它画出来,作为一种粗略的草图:

...--c1--c2--c3--c4--m1--...--mn   <-- master
                    \
                     t1--...--tn   <-- topic

其中 c 提交对两个分支都是通用的,m 提交仅在 master 上,t 提交仅在 [=15= 上].提交 c4 是最后一个常见的。

I rewrote history on my master branch using git rebase, but forgot, that this included the commit that was the "last common ancestor" with my topic branch. In other words, if I now git log the master branch, I can't find the commit ID anymore of the "last common ancestor" commit with topic.

由于 rebase 通过 复制 提交,然后移动分支名称以指向最后复制的提交,让我们现在绘制它,使用 ' 后缀来显示复制的提交:

        c2'-c3'-c4'-m1'-...--mn'  <-- master
       /
...--c1--c2--c3--c4--m1--...--mn   [abandoned]
                   \
                    t1--...--tn   <-- topic

虽然您 可以topic 上使用 git log 来查找提交 c4,但它实际上并不是 sharedmaster 了。

I assume the "last common ancestor" commit hasn't been garbage collected yet, since it is still referenced by the topic branch. But it isn't part of the master branch anymore.

完全正确:虽然 m1-...-mn 被“遗弃”,但 c4 不是 。 (请注意,这些提交的哈希 ID 可能至少在两个 reflog 中:一个用于 master,另一个用于 HEAD。这些 reflog 条目将使提交保持活动状态,直到 reflog 条目本身过期.)

What happens now, if I now try to merge topic with master?

合并操作将找到第一个实际共同的提交,现在是 c1,并将 c1(它的快照)的内容与 mn 的内容进行比较(大师提示)查看您在 master 上更改的内容,然后将 c1tn 进行比较以查看您在 topic 上更改的内容。然后它将合并这两个更改,如果成功,则自行进行合并提交:

        c2'-c3'-c4'-m1'-...--mn'
       /                       \
...--c1--c2--c3--c4             M   <-- master (HEAD)
                   \           /
                    t1--...--tn   <-- topic

(被遗弃的提交如果没有被 GC 处理,它们仍然在那里,但它们挡住了我停止绘制它们的方式。)git log of master 现在将显示重复的 c4-and-c4' 提交,c3-and-c3',等等。

要消除它们,请通过一些过程找到 c4c4'——例如,手动 git log 和目测,或使用 git cherry,或使用 git log --left-right --cherry-mark topic...master,或任何你喜欢的。一旦知道 c4c4' 在哪里,就可以使用命令 :

git checkout topic
git rebase --onto master <hash-of-c4>

(甚至只是将 topic 放在 git rebase 命令的末尾,但我不想这样做 - 从 master 开始并在 topic...).

我相信 torek 的回复将包含所有血淋淋的细节...这是我的简短回答:找到作为共同祖先的那个修订版的新旧 Id。

git rebase --onto new-id old-id topic

也就是在原为的位置得到分支......但也可以运行

git rebase --onto master old-id topic

放在新的主分支之上