0

可以说我有类似的历史。
Develop 会定期合并到 master 中。

a---b---c---d---i---j---k---o  master
 \             /           /
  e---f---g---h---l---m---n    develop

如何在不完全展平历史的情况下修改 b?
如果我以交互方式变基并修改 b,我最终会得到如下所示的历史记录:

(大写表示提交更改)

a---B---C---E---F---G---H---J---K---L---M---N  master
 \
  e---f---g---h---l---m---n                    develop

我怎样才能保留历史结构,让它看起来像这样:

a---B---C---D---I---J---K---O  master
 \             /           /
  e---f---g---h---l---m---n    develop
4

1 回答 1

4

从技术上讲,您无法更改任何现有提交的任何内容。

这意味着要“更改”bB,您实际上必须制作一个新的和改进的B. 旧的b将继续存在(多久,完全是另一个问题)。常规git rebase的、交互的或非交互的,通过将提交复制到新的和改进的提交来工作。正如您所指出的,常规 rebase 还会删除合并和展平。

从 Git 2.18 开始,git rebase就有了一个名为--rebase-merges. 这保留了合并——或者更准确地说,通过再次运行,将它们重新创建为新的合并提交git merge。2.18 之前的git rebasehas -p,它使用交互式 rebase 机制,否则也会保留合并(通过重复它们)。与更高级的新版本相比,它有些缺陷,但是——我认为(尚未测试!)——应该适用于这种情况。

因此,请使用git rebase -i --rebase-merges您将使用的方式git rebase -i。如果您缺少--rebase-merges,请更新您的 Git 版本,或者使用git rebase -i -p并非常小心不要扰乱各种操作的顺序,或者手动构建您的新链。

要手动构建它,请git checkout在 commit 上运行BHEAD如果您愿意,您可以在此处分配一个新的分支名称,或者只是以分离的方式执行整个操作,如下所示git rebase

git checkout -b temp-rebuild <hash-of-b>

例如,使用新的临时分支名称。然后使用git commit --amend(可能先使用其他东西)来制作新的B

  B   <-- temp-rebuild
 /
a---b---c---d---i---j---k---o   <-- master
 \             /           /
  e---f---g---h---l---m---n   <-- develop

现在git cherry-pick在提交的哈希上运行c以将其复制到新的提交C,并重复d

  B---C---D   <-- temp-rebuild
 /
a---b---c---d---i---j---k---o   <-- master
 \             /           /
  e---f---g---h---l---m---n   <-- develop

现在git merge在 commit 的第二个父级的哈希上h运行进行新的 merge i,如果需要解决任何合并冲突:I

  B---C---D------I   <-- temp-rebuild
 /              /
a---b---c---d--/i---j---k---o   <-- master
 \            |/           /
  e---f---g---h---l---m---n   <-- develop

使用更多的cherry-pick和merge命令来完成这个过程:

  B---C---D------I---J---K--O   <-- temp-rebuild
 /              /          /
a---b---c---d--/i---j---k-|-o   <-- master
 \            |/          |/
  e---f---g---h---l---m---n   <-- develop

现在构建了新的提交,强制名称master指向最终提交,并停止绘制旧b-c-d-i-j-k-o链,你就得到了你想要的。这是做什么git rebase --rebase-mergesgit rebase -p做的:-p只使用一个脆弱的算法,同时--rebase-merges使用一种新的交互式指令表格式,它允许您以一种在移动提交时不会中断的方式指定新图形。

于 2019-10-29T18:29:39.707 回答