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

  • git cherry pick commit命令将命名commit引入的更改应用于当前分支。它将引入一种新的, 不同的提交。严格地说,使用git cherry pick不会 更改存储库中的现有历史记录;相反,它增加了成本 历史

    F'=(F-B)+Z正确吗

  • git revert commit命令与git cherry pick commit命令基本相似,但有一个重要区别: 它应用给定提交的相反结果。因此,这个命令是 用于引入一个新的提交,该提交会反转给定提交的效果 承诺

    D'=G-D是正确的吗


  • 这样理解很简单:

    cherry pick
    选择哪些提交(来自任何分支,甚至可以是松散提交)选择此提交并将其放置在我的当前分支中,换句话说,从存储库中的任何位置进行任何提交将其添加到我的分支中


    还原
    撤消任何提交。如果您知道什么是修补程序,它将通过撤消它们来“还原”提交中所做的任何更改,以便您可以将其视为在修补程序中反转符号
    -
    变为COMMIG
    +
    ,反之亦然。您的更改正在被“还原”,并且更改正在撤消

    git revert命令撤消提交的快照

    但是,不是从项目历史记录中删除提交,
    它指出了如何撤消提交引入的更改,并将结果内容附加到新的提交中

    可以防止Git丢失历史记录
    ,这对于修订历史记录的完整性和可靠的协作非常重要


    F'=(F-B)+Z正确吗

    这仅仅意味着,现在在较低的分支中,您也有了在commit F中创建的补丁,较低的分支包含了它的更改+在commit F中所做的更改(并且除了F之外没有其他提交)


    D'=G-D是正确的吗?

    不完全是这样-这意味着现在您有了提交D,在几次提交之后,您有了对该提交的撤消,在存储库中您仍然有两次提交,但代码将保持不变(在两次单独提交时更改+撤消)

    F'=(F-B)+Z正确吗

    不,这也会引入在CDE中引入的更改

    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
    
    CD的父项)的内容是:

    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行!
    )。