Git cherry pick和revert是如何工作的?
我试图理解合并和重基在数学中的集合运算方面做了什么 在下面的例子中,“-”表示Git cherry pick和revert是如何工作的?,git,git-revert,git-cherry-pick,Git,Git Revert,Git Cherry Pick,我试图理解合并和重基在数学中的集合运算方面做了什么 在下面的例子中,“-”表示diff(类似于在数学中取集差,但“A-B”表示A中的集差而不是B中的集差,减去B中的集差而不是A中的集差),“+”表示patch(即在数学中取不相交的并集。我以前没有用过patch,所以我不确定) 来自Loeliger的Git版本控制,2ed git cherry pick commit命令将命名commit引入的更改应用于当前分支。它将引入一种新的, 不同的提交。严格地说,使用git cherry pick不会
diff
(类似于在数学中取集差,但“A-B”表示A中的集差而不是B中的集差,减去B中的集差而不是A中的集差),“+”表示patch
(即在数学中取不相交的并集。我以前没有用过patch
,所以我不确定)
来自Loeliger的Git版本控制,2ed
这样理解很简单:
cherry pick
选择哪些提交(来自任何分支,甚至可以是松散提交)选择此提交并将其放置在我的当前分支中,换句话说,从存储库中的任何位置进行任何提交将其添加到我的分支中
还原
撤消任何提交。如果您知道什么是修补程序,它将通过撤消它们来“还原”提交中所做的任何更改,以便您可以将其视为在修补程序中反转符号-
变为COMMIG+
,反之亦然。您的更改正在被“还原”,并且更改正在撤消
git revert命令撤消提交的快照
但是,不是从项目历史记录中删除提交,它指出了如何撤消提交引入的更改,并将结果内容附加到新的提交中 这
可以防止Git丢失历史记录
,这对于修订历史记录的完整性和可靠的协作非常重要
F'=(F-B)+Z正确吗 这仅仅意味着,现在在较低的分支中,您也有了在commit F中创建的补丁,较低的分支包含了它的更改+在commit F中所做的更改(并且仅除了F之外没有其他提交)
D'=G-D是正确的吗? 不完全是这样-这意味着现在您有了提交D,在几次提交之后,您有了对该提交的撤消,在存储库中您仍然有两次提交,但代码将保持不变(在两次单独提交时更改+撤消) F'=(F-B)+Z正确吗 不,这也会引入在C、D和E中引入的更改
git cherry-pick
的工作原理是隔离要cherry-pick的提交中的唯一更改(即本例中的F-E,忽略包括合并基在内的其他祖先),并将其应用于目标
这不是通过补丁应用程序来完成的,而是通过使用三方合并算法来完成的——要挑选的提交的父级将用作公共祖先,而要挑选的提交将是合并的一方,目标是另一方。其结果是包括在提交和目标中的更改
例如,如果E是要挑选的提交的父级,其内容(充当公共祖先)为:
例如,如果F是要挑选的提交,其内容为:
Line 1
Line 2
Line Three
Line 4
Line 5
Line 1
Line 2
Line THREE
Line 4
Line FIVE
Line One
Line 2
Line THREE
Line 4
Line FIVE
樱桃采摘Z的目标是:
LINE 1
Line 2
Line 3
Line 4
Line 5!
然后,三向合并的结果是(带有关于每行来自何处的注释):
还原
D'=G-D是正确的吗
是的,粗略地说。D特有的变化已从G中删除。与git cherry pick
类似,git revert
是使用三方合并实现的,尽管这次提交到还原被视为公共祖先,一方是当前提交,另一方是提交到还原的父级
这意味着,当要还原的提交和当前提交之间的行相同时,将选择来自其父级的行
如果D的内容,则提交还原将充当公共祖先,其内容为:
Line 1
Line 2
Line Three
Line 4
Line 5
Line 1
Line 2
Line THREE
Line 4
Line FIVE
Line One
Line 2
Line THREE
Line 4
Line FIVE
而C(D的父项)的内容是:
G的内容发生了进一步的变化,其内容如下:
Line 1
Line 2
Line Three
Line 4
Line 5
Line 1
Line 2
Line THREE
Line 4
Line FIVE
Line One
Line 2
Line THREE
Line 4
Line FIVE
然后,三方合并的结果将是:
Line One
Line 2
Line 3
Line 4
Line 5
这是在父级C和目标G中获取唯一行的结果
合并提交
如下所述,由于这些机制都涉及使用父提交,因此当存在多个父提交时,这些机制就会崩溃。(即,提交的问题是合并并具有多个父级)。在这种情况下,您需要指定Git要考虑的父类(使用<代码> -M/COD>标志)。
冲突
当然,这两种机制都可能导致冲突。例如,如果当前冲突已进一步更改,则必须解决冲突。例如,如果在上面的revert示例中,后续提交也更改了第5行,那么G实际上是:
Line One
Line 2
Line THREE
Line 4
LINE FIVE!
然后就会发生冲突。工作目录(合并文件)将是:
Line One
Line 2
Line 3
Line 4
<<<<<<<
LINE FIVE!
=======
Line 5
>>>>>>>
第一行
第2行
第3行
第4行
>
您需要决定是要原始更改(第5行
)还是最新更改(第5行!
)。