当您合并不相关的历史记录时,git 中会发生什么?
What happens in git when you merge unrelated histories?
我正在处理不相关的历史,我知道我可以使用 --allow-unrelated-histories
强制 git 合并它们。但是,默认情况下禁用此选项。这一定是有原因的,我很难找到任何关于使用该选项时会发生什么以及为什么默认情况下禁用它的文档。
此选项的具体作用是什么?为什么我不想使用它?
例如,假设我创建了一个新项目并发生了以下情况:
我生成了两个提交并将它们推送到远程
master : a -> b
origin/master : a -> b
然后,当我处理更多提交时,远程提交被修改或替换(我知道这听起来很糟糕,但在使用 Gerrit 并将更改应用于补丁集时这是一个非常有效的工作流程)
master : a -> b -> c -> d -> e
origin/master : a'-> b'
如果我 git 拉 --allow-unrelated-histories
会怎样?这棵树长什么样?我的本地分支是否堆叠提交或是否存在冲突解决或其他问题?
通常,当您进行合并时,Git 会考虑三个(且仅三个)点:两个头和合并基,通常是最近的共同祖先。三向合并需要这三个点,Git 通过基本上将每一侧的更改(当针对合并基础计算时)应用到公共树中来实现。
然而,当你合并不相关的历史时,共同的祖先是空树,所以你可能会以 很多 的 add/add 冲突和普遍的悲伤结束,如果你试着这样做。发生这种情况通常是无意的并且是错误的,因此如果您确实需要它(您在此处执行此操作),可以选择启用它。
在这种情况下进行合并的最佳方法是尝试合并两棵相同的树,或者至少合并两棵彼此差异尽可能小的树。如果两个文件在两个头中相同(即,它们的 blob 具有相同的对象 ID),Git 将通过获取该结果平凡地合并它们,因此根据定义,相同文件或相同树没有合并冲突.
你可能会 运行 遇到与 rebase 相同的问题,因为 rebase 应用补丁或在后台进行合并,你将 运行 遇到类似的问题无论哪种方式,所以合并可能是您的最佳选择。
你的分支,当你完成合并时,仍然有两个根,所以你最终会得到这样的东西(其中 f
是你的合并提交):
a - b - c - d - e - f
a' - b' -------------/
我正在处理不相关的历史,我知道我可以使用 --allow-unrelated-histories
强制 git 合并它们。但是,默认情况下禁用此选项。这一定是有原因的,我很难找到任何关于使用该选项时会发生什么以及为什么默认情况下禁用它的文档。
此选项的具体作用是什么?为什么我不想使用它?
例如,假设我创建了一个新项目并发生了以下情况:
我生成了两个提交并将它们推送到远程
master : a -> b
origin/master : a -> b
然后,当我处理更多提交时,远程提交被修改或替换(我知道这听起来很糟糕,但在使用 Gerrit 并将更改应用于补丁集时这是一个非常有效的工作流程)
master : a -> b -> c -> d -> e
origin/master : a'-> b'
如果我 git 拉 --allow-unrelated-histories
会怎样?这棵树长什么样?我的本地分支是否堆叠提交或是否存在冲突解决或其他问题?
通常,当您进行合并时,Git 会考虑三个(且仅三个)点:两个头和合并基,通常是最近的共同祖先。三向合并需要这三个点,Git 通过基本上将每一侧的更改(当针对合并基础计算时)应用到公共树中来实现。
然而,当你合并不相关的历史时,共同的祖先是空树,所以你可能会以 很多 的 add/add 冲突和普遍的悲伤结束,如果你试着这样做。发生这种情况通常是无意的并且是错误的,因此如果您确实需要它(您在此处执行此操作),可以选择启用它。
在这种情况下进行合并的最佳方法是尝试合并两棵相同的树,或者至少合并两棵彼此差异尽可能小的树。如果两个文件在两个头中相同(即,它们的 blob 具有相同的对象 ID),Git 将通过获取该结果平凡地合并它们,因此根据定义,相同文件或相同树没有合并冲突.
你可能会 运行 遇到与 rebase 相同的问题,因为 rebase 应用补丁或在后台进行合并,你将 运行 遇到类似的问题无论哪种方式,所以合并可能是您的最佳选择。
你的分支,当你完成合并时,仍然有两个根,所以你最终会得到这样的东西(其中 f
是你的合并提交):
a - b - c - d - e - f
a' - b' -------------/