无法理解为什么 git merge -s ours 会忽略以前的提交
Can't understand why git merge -s ours will ignore previous commits
几个小时以来,我一直在阅读有关 git merge -s ours
策略的内容。我发现的所有资源都表明它会欺骗 Git 忽略在使用 -s ours
策略进行的“假”合并之前发生的提交,我不明白为什么:
假设我有以下 git 历史,master
和 feature
分支之间有很多差异:
(A)------(B)-------(C)------(D) <---[master] <---[HEAD]
\
\
(E)------(F)------(G) <---[feature]
现在我运行git merge -s ours feature
,结果是提交H
:
(A)------(B)-------(C)------(D)--(H) <---[master] <---[HEAD]
\ /
\ /
(E)------(F)--------------(G) <-- [feature]
然后我在两个分支上做更多的提交:
(A)------(B)-------(C)------(D)--(H)------(K)------(L) <---[master] <---[HEAD]
\ /
\ /
(E)------(F)--------------(G)------(I)------------(J) <-- [feature]
然后,在 master
我 运行 git merge feature
如有错误请指正,届时Git将:
- 将提交
G
计算为 merge-base
- 运行
G
和 L
的区别
- 运行
G
和 J
之间的区别
- 复制提交
G
,说 G'
并将上述 2 个差异应用到提交 G'
- 使
L
和J
成为G'
的parents
这是我不明白的地方: 根据文档,提交 E
和 F
的更改不会影响合并,但是G
和 L
之间的差异仍将 反映在提交 E
和 F
中所做的更改 因为 G
是从他们“诞生”,那么仅仅因为使用了 ours
策略,这些提交中的更改怎么可能不会影响合并?
在更极端的情况下,如果这些分支分歧更大,例如 feature
分支中有 100 个文件(在 G
之前引入)并且 not 在 master
中,那么 上次合并期间它们是否仍会出现在 G
和 L
之间的差异中? **编辑:我不明白为什么它们不会出现在 diff
不,G
和 L
之间的 差异 不反映 E
和 F
的变化。如果 I
引入了更改,它将显示在 diff 中,但之前的更改不包含在 diff 中。
如您所写:G
被检测为合并基础,其他所有内容均从那里计算。
也许以下内容有帮助:
E
添加文件 e
F
添加文件 f
G
包含文件 e
和 f
.
H
包含 与 D
相同的 树
I
添加文件 i
G
和 I
之间的差异仅包含 在 G
之后的变化,即新文件 i
。由于文件 e
和 f
之后都没有更改,因此它们不会出现在 diff 中。就 Git 而言,这些更改已经合并(但“解决”为不显示在最终结果中,只有“我们的”树是结果的一部分)。
从 Git 的角度来看,G
之前的更改在与策略 ours
合并时会恢复。您可以通过比较两个提交来确认这一点:git diff G H
将向您准确显示 E
和 F
(或者 A..G
,如果您愿意的话)的反向变化。
git merge -s ours feature
提交 (H)
的树现在是 (D)
的副本。从 (G)
到 (H)
,您会看到 (A)
到 (G)
正在撤消,B...D
正在完成。
后面的合并以G为基数。 G...L
撤消 A...G 撤消,然后 A...L 完成。 G...J
查看功能更改。
这些更改已合并。
G->H
转换包含 A...G
的撤消,因为您告诉它这样做。
几个小时以来,我一直在阅读有关 git merge -s ours
策略的内容。我发现的所有资源都表明它会欺骗 Git 忽略在使用 -s ours
策略进行的“假”合并之前发生的提交,我不明白为什么:
假设我有以下 git 历史,master
和 feature
分支之间有很多差异:
(A)------(B)-------(C)------(D) <---[master] <---[HEAD]
\
\
(E)------(F)------(G) <---[feature]
现在我运行git merge -s ours feature
,结果是提交H
:
(A)------(B)-------(C)------(D)--(H) <---[master] <---[HEAD]
\ /
\ /
(E)------(F)--------------(G) <-- [feature]
然后我在两个分支上做更多的提交:
(A)------(B)-------(C)------(D)--(H)------(K)------(L) <---[master] <---[HEAD]
\ /
\ /
(E)------(F)--------------(G)------(I)------------(J) <-- [feature]
然后,在 master
我 运行 git merge feature
如有错误请指正,届时Git将:
- 将提交
G
计算为merge-base
- 运行
G
和L
的区别
- 运行
G
和J
之间的区别
- 复制提交
G
,说G'
并将上述 2 个差异应用到提交G'
- 使
L
和J
成为G'
的parents
这是我不明白的地方: 根据文档,提交 E
和 F
的更改不会影响合并,但是G
和 L
之间的差异仍将 反映在提交 E
和 F
中所做的更改 因为 G
是从他们“诞生”,那么仅仅因为使用了 ours
策略,这些提交中的更改怎么可能不会影响合并?
在更极端的情况下,如果这些分支分歧更大,例如 feature
分支中有 100 个文件(在 G
之前引入)并且 not 在 master
中,那么 上次合并期间它们是否仍会出现在 G
和 L
之间的差异中? **编辑:我不明白为什么它们不会出现在 diff
不,G
和 L
之间的 差异 不反映 E
和 F
的变化。如果 I
引入了更改,它将显示在 diff 中,但之前的更改不包含在 diff 中。
如您所写:G
被检测为合并基础,其他所有内容均从那里计算。
也许以下内容有帮助:
E
添加文件e
F
添加文件f
G
包含文件e
和f
.H
包含 与D
相同的 树
I
添加文件i
G
和I
之间的差异仅包含 在G
之后的变化,即新文件i
。由于文件e
和f
之后都没有更改,因此它们不会出现在 diff 中。就 Git 而言,这些更改已经合并(但“解决”为不显示在最终结果中,只有“我们的”树是结果的一部分)。
从 Git 的角度来看,G
之前的更改在与策略 ours
合并时会恢复。您可以通过比较两个提交来确认这一点:git diff G H
将向您准确显示 E
和 F
(或者 A..G
,如果您愿意的话)的反向变化。
git merge -s ours feature
提交 (H)
的树现在是 (D)
的副本。从 (G)
到 (H)
,您会看到 (A)
到 (G)
正在撤消,B...D
正在完成。
后面的合并以G为基数。 G...L
撤消 A...G 撤消,然后 A...L 完成。 G...J
查看功能更改。
这些更改已合并。
G->H
转换包含 A...G
的撤消,因为您告诉它这样做。