将“master”合并到“final”,然后将其合并回“master”会更好(更安全)吗?还是从“final”直接合并到“master”会保留之前的提交?
后者:从“final”直接合并到“master”,保留之前的提交。
git 与 SVN 等其他版本控制系统不同。对于不熟悉的人,SVN 将分支视为“桶”——分支/桶是固定的(稳定的),您必须小心在桶之间移动提交。在 SVN 中,在将“最终”分支“重新集成”(伪合并)回“主”之前,您必须将任何最近的“主”提交合并(复制)到“最终”中。 'Reintegration' 有效地将 'final' 的尖端复制到 'master' 的尖端,有效地将 'master' 替换为 'final' 的尖端的精确副本。您可能会丢失“master”中未首先合并(复制)到“final”的任何提交。
就像我说的,git 是不同的。在 git 中,我喜欢将存储库树(提交)视为稳定的,而不是将其视为移动的“分支”——将分支视为挂在提交上的小标签/装饰。
我要画你的树有点不同 - 事实上,我会在创建提交'i'之前绘制它:
final
|
e - g
/
a - b - c
\
d - f - h
|
master
现在让我们提交'i':
final
|
e - g - i
/
a - b - c
\
d - f - h
|
master
只有两件事发生了变化。 (1)暂时忽略分支“装饰”,我们看到新提交“i”是从其父提交“g”创建的,(2)最终“装饰”从提交“g”移动到“i”。
让我们将 final 合并到 master 中——也就是说,让我们更新 master 以便它包含来自 final 的更改:
final
|
e - g - i
/ \
a - b - c j
\ /|
d - f - h |
|
master
现在'master'分支装饰移动了。 “最终”的分支装饰保持不变。 “j”提交是从 2 个父项创建的合并提交:“h”和“i”。
但是,如果我们将 master 合并到 final 中会怎样——也就是说,更新 final 以便它包含来自 master 的更改:
final
|
e - g - i |
/ \|
a - b - c j
\ /
d - f - h
|
master
现在“final”移动了,“master”留在了原地。请注意,合并是真正的合并 - 两个分支的更改都在提交“j”中。无论哪个分支合并到哪个分支,'j' 都是相同的 - 唯一的区别是哪个分支“装饰”被移动了。 (而且那些分支“装饰”很容易移动。)
为了完整起见,让我们将另一个分支合并回第一个分支(谁先合并到谁并不重要——只要我们这次向另一个方向合并)。请注意,只有装饰移动 - 不需要新的提交(在 git 行话中,它是“快进”),因为“j”已经包含来自两个分支的两组更改:
final
|
e - g - i |
/ \|
a - b - c j
\ /|
d - f - h |
|
master
事实上,让我们在几天后看看树(我删除了'final'分支 - 我已经完成了它):
e - g - i
/ \
a - b - c j - k - l - m
\ / |
d - f - h |
|
master
好的,你能从树上分辨出哪个分支最初是“主”,哪个分支最初是“最终”:e-g-i 还是 d-f-h?有关系吗?
在 git 中,合并是真正的合并。没有“桶”,您不必像 SVN 那样在“桶”/分支之间移动提交。只有您正在进化的“树”和分支(“装饰”)正在为您在其中的位置添加书签。