我正在尝试理解在数学集合操作中,merge和rebase的含义。
在下文中,“-”表示diff
(类似于在数学中进行集合差分,但“A-B”的意思是属于A而不属于B,减去B中不属于A的元素),“+”表示patch
(即在数学中进行不相交并集。我以前没有使用过patch
,所以不确定)。
以下内容来自《使用Git进行版本控制,作者为Loeliger,第2版》
我正在尝试理解在数学集合操作中,merge和rebase的含义。
在下文中,“-”表示diff
(类似于在数学中进行集合差分,但“A-B”的意思是属于A而不属于B,减去B中不属于A的元素),“+”表示patch
(即在数学中进行不相交并集。我以前没有使用过patch
,所以不确定)。
以下内容来自《使用Git进行版本控制,作者为Loeliger,第2版》
F' = (F-B) + Z,这个公式是正确的吗?
不正确,这样会将C、D和E所做的更改也一并引入。
git-cherry-pick
通过隔离要挑选的提交记录中的唯一更改内容(即,本例中的F-E,忽略其他祖先,包括合并基础),并将它们应用到目标上来实现挑选。
这并不是通过补丁应用来完成的,而是通过使用三方合并算法 - 要挑选的提交记录的父级将被用作公共祖先,要挑选的提交记录将成为一个合并的一侧,目标将成为另一侧。最终产生的结果是已包含在挑选的提交记录和目标中的更改。
例如,如果E是要挑选的提交记录的父级,则其内容(作为公共祖先)应为:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 1
Line 2
Line Three
Line 4
Line 5
而 cherry-pick Z 的目标是:
LINE 1
Line 2
Line 3
Line 4
Line 5!
三路合并的结果如下(带有每行来自哪里的注释):
LINE 1
Line 2
Line Three
Line 4
Line 5!
D' = G - D,这个说法正确吗?
大致上是的。唯一属于D的更改已从G中移除。与git-cherry-pick
类似,git-revert
使用三方合并实现,但这次要将被还原的提交视为公共祖先,一边是当前提交,另一边是要还原的提交的父提交。
这意味着,当一行在要还原的提交和当前提交之间相同时,将选择其父提交中的行。
如果要还原的提交D的内容充当公共祖先,并且其内容为:
Line 1
Line 2
Line THREE
Line 4
Line FIVE
而 C(D 的父级)的内容如下:
Line 1
Line 2
Line 3
Line 4
Line 5
G的内容已进一步更改,现在它的内容如下:
Line One
Line 2
Line THREE
Line 4
Line FIVE
Line One
Line 2
Line 3
Line 4
Line 5
从父C和目标G中获取唯一行的结果。
正如torek所指出的那样(如下所示),由于这些机制都涉及使用父提交,因此当存在多个父提交时,它们将会失效。 (即,所讨论的提交是合并提交并具有多个父提交)。在这种情况下,您需要指定要考虑哪个父提交(使用-m
标志)。
当然,这两种机制都可能导致冲突。例如,如果当前冲突已经进一步更改,则必须解决冲突。例如,在上面的还原示例中,如果随后的提交也更改了第5行,则G实际上应该是:
Line One
Line 2
Line THREE
Line 4
LINE FIVE!
这会导致冲突。合并后的工作目录将如下:
Line One
Line 2
Line 3
Line 4
<<<<<<<
LINE FIVE!
=======
Line 5
>>>>>>>
您需要决定是要原始更改 (第5行
) 还是最新更改 (第五行!
)。
E
或还原 D
时,你不需要这样做,因为它们已经只有一个前任节点。 - torek如下所示,很容易理解:
cherry-pick
选择任何分支或松散提交的哪些提交,并将其选定并放置在当前分支中,换句话说 - 从存储库中获取任何提交并将其带到我的分支中。
revert
撤消任何提交。它将通过撤销提交中所做的任何更改来“还原”它们,如果您知道什么是补丁,则可以将其视为在补丁中翻转符号-
变为+
反之亦然。您的更改正在“还原”,并且更改正在被撤消。
git revert命令撤消了已提交的快照。
但是,它不会从项目历史记录中删除提交,而是找出如何撤消提交引入的更改,并追加一个包含结果内容的新提交。
这样做可以
防止Git丢失历史记录
,这对您的修订历史和可靠的协作很重要。
F' = (F-B) + Z是否正确?
这意味着现在在较低分支中,还包含创建在提交F中的补丁,您的较低分支包含其更改+提交F中所做的更改(只有这些更改,除了F没有其他提交)。
D' = G-D是否正确?
不完全正确 - 这意味着现在您拥有提交D,并在几个提交之后进行了撤消,存储库中仍然存在2个提交,但代码将保持不变(2个单独提交上的更改和撤消)。
bk2204
) 提交。gitster
--合并于提交 c5a8f1e,2020年9月29日)
文档
:解释为什么在合并时不总是应用还原操作。 签名:brian m. carlson
常见情况是用户将更改应用于一个分支并将其挑选到另一个分支中,然后稍后在第一个分支中撤销更改。这会导致当两个分支合并时出现更改存在的情况,这让许多用户感到困惑。git merge
(man)如何工作的文档,但从频繁提问的情况来看,很明显这很难理解。
我们也没有向用户解释,在这种情况下最好使用 rebase,它会实现他们的意图。gitfaq
在其手册页面中包括了上述内容。git rebase
中的“注意事项”部分。