采摘和还原如何工作? [英] How do cherry-pick and revert work?

查看:95
本文介绍了采摘和还原如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据数学中的集合运算来理解合并和变基的作用.

在下文中,-"表示diff(类似于在数学上求集合差,但"AB"表示A中但不在B中的值,减去B中不在A中的值),"+"表示patch(即在数学中采用不相交的并集.我以前没有使用过patch,所以我不确定).

摘自Loeliger,2ed版,《带有Git的版本控制》

  1. 命令git cherry-pick commit在当前分支上应用由命名提交引入的更改.它将引入一个新的 独特的提交.严格来说,使用git cherry-pick不会 更改存储库中的现有历史记录;相反,它增加了 历史.

    F'=(F-B)+ Z是否正确?

  2. git revert commit命令与git cherry-pick commit命令基本相似,但有一个重要区别: 它应用给定提交的反函数.因此,此命令是 用于引入新的提交,该提交可以逆转给定的结果 提交.

    D'= G-D是否正确?

解决方案

樱桃采摘

F'=(F-B)+ Z是否正确?

否,这还将引入在 C D E 中引入的更改.

git-cherry-pick的工作方式是隔离待樱桃选择的提交中的唯一更改(即,在此示例中为 FE ,忽略包括合并基础的其他祖先),并将其应用于目标

这不是使用修补程序应用程序完成的,而是通过使用三种方式的合并算法-要选择樱桃的提交的父级将用作公共祖先,要选择樱桃的提交将是一侧合并,目标是另一侧.其结果是在精心挑选的提交和目标中包含的更改.

例如,如果 E 是要进行选择的提交的父级,则其内容(作为共同祖先)为:

Line 1
Line 2
Line 3
Line 4
Line 5

例如,如果 F 是要挑选的提交,则其内容为:

Line 1
Line 2
Line Three
Line 4
Line 5

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 所述,由于这些机制都涉及使用父提交,因此当存在多个父提交. (即,所讨论的提交是合并的,并且具有多个父对象.)在这种情况下,您需要指定git 要考虑的父对象(使用-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
>>>>>>>

您将需要决定是要原始更改(Line 5)还是最新更改(LINE FIVE!).

I am trying to understand what merge and rebase do, in terms of set operations in math.

In the following, "-" means diff (similar to taking set difference in math, but "A-B" means those in A but not in B and minus those in B not in A), and "+" means patch (i.e. taking disjoint union in math. I haven't used patch before, so I am not sure).

From Version Control with Git, by Loeliger, 2ed

  1. The command git cherry-pick commit applies the changes introduced by the named commit on the current branch. It will introduce a new, distinct commit. Strictly speaking, using git cherry-pick doesn’t alter the existing history within a repository; instead, it adds to the history.

    Is it correct that F' = (F-B) + Z?

  2. The git revert commit command is substantially similar to the command git cherry-pick commit with one important difference: it applies the inverse of the given commit. Thus, this command is used to introduce a new commit that reverses the effects of a given commit.

    Is it correct that D' = G - D?

解决方案

cherry-pick

Is it correct that F' = (F-B) + Z?

No, that would also introduce the changes that were introduced in C, D and E.

git-cherry-pick works by isolating the unique changes in the commit to be cherry-picked (ie, F-E in this example, ignoring additional ancestors including the merge base), and apply them to the target.

This is not done with patch application, but by using the three way merge algorithm - the parent of the commit to be cherry-picked will be used as the common ancestor, and the commit to be cherry-picked will be one side of the merge, with the target as the other side. The product of this is the changes that were included in the cherry-picked commit and in the target.

For example, if E is the parent of the commit to be cherry-picked, and its contents (acting as the common ancestor) are:

Line 1
Line 2
Line 3
Line 4
Line 5

For example, if F is the commit to be cherry-picked, and its contents are:

Line 1
Line 2
Line Three
Line 4
Line 5

And the target of the cherry-pick Z is:

LINE 1
Line 2
Line 3
Line 4
Line 5!

Then the results of a three-way merge are (with annotations about where each line came from):

LINE 1
Line 2
Line Three
Line 4
Line 5!

revert

Is it correct that D' = G - D?

Yes, roughly speaking. The changes that were unique to D have been removed from G. Like git-cherry-pick, git-revert is implemented using a three-way merge, though this time the commit to revert is treated as the common ancestor, one side is the current commit and the other side is the commit to revert's parent.

This will mean that when a line is identical between the commit to revert and the current commit, the line from its parent will be chosen instead.

If the contents of D, the commit to revert is acting as the common ancestor, and its contents are:

Line 1
Line 2
Line THREE
Line 4
Line FIVE

And the contents of C (D's parent) are:

Line 1
Line 2
Line 3
Line 4
Line 5

And the contents of G has been changed further, and its contents are:

Line One
Line 2
Line THREE
Line 4
Line FIVE

Then the results of the three-way merge will be:

Line One
Line 2
Line 3
Line 4
Line 5

Which is the result of taking the unique lines in the parent C and the target G.

Merge Commits

As torek notes (below), since these mechanisms both involve using a parent commit, these break down when there are more than one parent commit. (Ie, the commit in question is a merge and has multiple parents.) In this case, you will need to specify to git which parent to consider (using the -m flag).

Conflicts

Of course, either of these mechanisms may cause conflicts. For example, if the current conflict had further changed then you will have to resolve conflicts. For example, if in the revert example (above), a subsequent commit had also changed line 5, so G had actually been:

Line One
Line 2
Line THREE
Line 4
LINE FIVE!

Then there would be a conflict. The working directory (merged file) would be:

Line One
Line 2
Line 3
Line 4
<<<<<<<
LINE FIVE!
=======
Line 5
>>>>>>>

And you will need to decide whether you want the original change (Line 5) or the newest change (LINE FIVE!).

这篇关于采摘和还原如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆