当前位置:  开发笔记 > 开发工具 > 正文

合并和转换如何工作?

如何解决《合并和转换如何工作?》经验,为你挑选了1个好方法。

我试图理解merge和rebase在数学中的集合操作方面做了什么.

在下文中," - "表示diff(类似于数学中的设定差异,但"AB"表示A中的但不表示B中的表示,而B表示不表示A中的表示,而"+"表示patch(即表示不相交联合)数学.我以前没用过patch,所以我不确定).

    来自Chacon的Pro Git,

    在此输入图像描述

    最近共同祖先C2在这次合并中的作用是什么?

    C5 =(C4-C2)+(C3-C2)+ C2是否正确?

    对于rebase而不是merge:

    在此输入图像描述

    C4'=(C4-C2)+ C3是正确的吗?

    那么C5来自merge并且来自rebase的C4'具有相同的内容吗?

    来自Loeliger的Git版本控制

    在此输入图像描述

    W',X',Y'和Z'是如何产生的?

poke.. 6

你无法使用"diff"和"patch"语义正确地解释Git.原因是Git没有跟踪变化; 它跟踪内容.当你有一个提交A与父母提交B,那么对于Git的,A是不是之间的差异BA,即从需要得到改变BA,但实际内容A.您可以自己进行提交,并且您可以在此时重建存储库.

出于这个原因,我不会遵循你的"提交算术",而是试着用文字解释每个案例.

    C5是两个父母C3和C4的合并提交,它们都有C2作为父母.因此,假设没有冲突,并且Git能够自己解析整个合并,那么C5将包含由以下两个等价表达式表示的内容:

    C3应用了补丁,可以让你从C2到C4.

    C4应用了补丁,可以让你从C2到C3.

    所以在某种程度上,你可以用你的公式来表达它.

    一个rebase基本上会让你处于完全相同的情况.唯一的区别是它实际上重写了它重新提交的提交,将它们的更改(补丁)重新应用到另一个提交.因此结果C4将具有与C5(1)相同的内容.

    有了你的"算术",我一般会这么说(C3-C2) + C2 = C3.所以这两个公式在这里也是等价的.

    如上所述,rebase只是将提交补丁重新应用到另一个父级.Git正在编写包含与原始提交相同更改的新提交,但这些新提交将应用于不同的父提交.

    因此,如果你想获得公式,它可能看起来像这样:

    W' = E  + (W - B)        (the patch from B to W, applied on E)
    X' = W' + (X - W)        (the patch from W to X, applied on W')
    Y' = X' + (Y - X)        (the patch from X to Y, applied on X')
    Z' = Y' + (Z - Y)        (the patch from Y to Z, applied on Y')
    

    因此,W更改的基础E代替B,并且所有后续提交都会更新,以便继续执行新的提交W'.

    但同样,其结果Z'具有相同内容的合并提交该合并的EZ必须.

这一切都给我们留下了一个问题:如果两者产生相同的内容,合并和rebase之间的区别是什么?由于您不会以两种方式丢失提交(rebase将创建新的提交对象,但这些将保留所有原始信息),基本上所有关于更改历史记录的方式:

合并创建一个合并提交,允许清楚地看到历史分歧的位置(创建分支的位置)以及它再次联合的位置.这很好,因为你可以按照确切的发展.但它也会变得混乱,特别是如果你有多个并发分支线,最终会合并多次.

另一方面,重新定位使历史持平.它"伪造"它,所以一切都是线性发展,一切都接连不断.由于您总是在重新设置一个完整的分支,因此您可以将相关提交保持在一起,这样您仍然可以看到彼此相关的内容,但是您丢失了任何分支信息.此外,您正在创建新的提交对象,这将破坏已经知道这些提交对象的每个人的存储库(这就是为什么您不应该重新设置已发布的提交).

两种方式都有利有弊.它在很大程度上取决于存储库工作流程和个人偏好.



1> poke..:

你无法使用"diff"和"patch"语义正确地解释Git.原因是Git没有跟踪变化; 它跟踪内容.当你有一个提交A与父母提交B,那么对于Git的,A是不是之间的差异BA,即从需要得到改变BA,但实际内容A.您可以自己进行提交,并且您可以在此时重建存储库.

出于这个原因,我不会遵循你的"提交算术",而是试着用文字解释每个案例.

    C5是两个父母C3和C4的合并提交,它们都有C2作为父母.因此,假设没有冲突,并且Git能够自己解析整个合并,那么C5将包含由以下两个等价表达式表示的内容:

    C3应用了补丁,可以让你从C2到C4.

    C4应用了补丁,可以让你从C2到C3.

    所以在某种程度上,你可以用你的公式来表达它.

    一个rebase基本上会让你处于完全相同的情况.唯一的区别是它实际上重写了它重新提交的提交,将它们的更改(补丁)重新应用到另一个提交.因此结果C4将具有与C5(1)相同的内容.

    有了你的"算术",我一般会这么说(C3-C2) + C2 = C3.所以这两个公式在这里也是等价的.

    如上所述,rebase只是将提交补丁重新应用到另一个父级.Git正在编写包含与原始提交相同更改的新提交,但这些新提交将应用于不同的父提交.

    因此,如果你想获得公式,它可能看起来像这样:

    W' = E  + (W - B)        (the patch from B to W, applied on E)
    X' = W' + (X - W)        (the patch from W to X, applied on W')
    Y' = X' + (Y - X)        (the patch from X to Y, applied on X')
    Z' = Y' + (Z - Y)        (the patch from Y to Z, applied on Y')
    

    因此,W更改的基础E代替B,并且所有后续提交都会更新,以便继续执行新的提交W'.

    但同样,其结果Z'具有相同内容的合并提交该合并的EZ必须.

这一切都给我们留下了一个问题:如果两者产生相同的内容,合并和rebase之间的区别是什么?由于您不会以两种方式丢失提交(rebase将创建新的提交对象,但这些将保留所有原始信息),基本上所有关于更改历史记录的方式:

合并创建一个合并提交,允许清楚地看到历史分歧的位置(创建分支的位置)以及它再次联合的位置.这很好,因为你可以按照确切的发展.但它也会变得混乱,特别是如果你有多个并发分支线,最终会合并多次.

另一方面,重新定位使历史持平.它"伪造"它,所以一切都是线性发展,一切都接连不断.由于您总是在重新设置一个完整的分支,因此您可以将相关提交保持在一起,这样您仍然可以看到彼此相关的内容,但是您丢失了任何分支信息.此外,您正在创建新的提交对象,这将破坏已经知道这些提交对象的每个人的存储库(这就是为什么您不应该重新设置已发布的提交).

两种方式都有利有弊.它在很大程度上取决于存储库工作流程和个人偏好.

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有