git之间的区别合并我们的他们的命令 [英] difference between git merge ours theirs commands

查看:188
本文介绍了git之间的区别合并我们的他们的命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在练习GIT。

  git merge -s我们的分支

git merge -s他们的分支

git合并-X我们的分支

git合并-X他们的分支

$ b $在我开始这个答案之前,让我强调,有两个不同的单词拼写为合并。有一个动词形式,要合并,这意味着合并更改。有一个名词或形容词形式,合并合并提交,指的是特定的提交类型。



git merge 命令通常会执行以下两个操作:它合并(动词)一些更改,然后使合并(名词)或合并提交(形容词)。不过,Git有许多方法来完成合并的动词形式。它还允许 git merge 命令省略最终的名词形式merge(但我们将在此完全忽略此案例)。



策略或扩展选项 - 简短版本



简短版本几乎不需要策略 em>选项 -s我们



使用 -X (扩展)选项,您可以告诉Git在发生冲突时倾向于合并的我们或他们一侧。也就是说,假设文件 wallaby.txt 的合并基本版本部分说明了:

 贝内特的小袋鼠是红宝石袋鼠的
a。

两个分支尖端版本之一 - 我们称之为左侧 local - 我们的版本说:

 贝内特的小袋鼠是红腹小袋鼠的
a小种。

另一个分支尖端版本,即右侧远程其他 - 他们的版本说:

 在塔斯马尼亚州发现的贝内特袋鼠,

是各种红颈袋鼠。

当我们将基本版本与两个分支提示进行比较时,对相同范围的行进行类似但不完全相同的更改:

  $ git diff $ base $ left 
...
贝内特的小袋鼠是
- 各种各样的红颈袋鼠。
+红色小袋鼠的小种类。
...

但:

  $ git diff $ base $ right 
...
- 贝内特的小袋鼠是
- 各种各样的红颈袋鼠。
+ Bennett的袋鼠,塔斯马尼亚的
+,
+是各种红颈袋鼠。

这两个更改会发生冲突,您将收到合并冲突



eXtended -X我们的选项意思是喜欢我们的改变:两个改变发生冲突,忽略他们的完全改变,取而代之的是 。 eXtended -X他们的选项意味着更喜欢他们的变化,即忽略我们的。



请注意,无论哪个更改你更喜欢,你会在这里失去一些东西。一个变化提到,贝内特的小袋鼠有点小,其他人提到它是塔斯马尼亚的形式。如果你选择一个,你会失去另一个。您可能应该手动合并这项变更,而不是让Git选择一方。



何时以及为什么您可以使用 -s我们的 对文件的更改,请使用 -s我们的



c>而不是 -X我们的对这个特定的文件级合并没有任何影响:无论哪种方式,我们都会采取我们(左侧)更改,并忽略他们的。但假设进一步的只有他们的版本修正了文件中其他地方的拼写错误:

  $ git diff $ base $ right 
...
-walaby
+ wallaby
...

$ left (本地或 - 我们的)输出中的内容完全不同。如果我们使用 -X我们的而不是 - 我们的,我们至少会拿起这个修正。当然,右侧可能会发生改变,而不是将它们删除,而是添加错别字。 Git不会知道或关心:它的工作是将这些变化结合起来,而不是决定它们是否有意义,无论是单独还是组合!



<此外,作为Tim Beigeleisen在上述评论中提及 -s我们的选项甚至不会查看右手边的差异。事实上,它根本不运行任何差异!它告诉Git以任何方式进行合并提交而不使用另一方。换句话说,它只是记录合并,而没有实际合并。

这样做的唯一理由是让合并的提交图历史记录。正如提交图本身所记录的那样,这是历史,它决定了你和Git将如何看到发生了什么,当你或其他人再回来看时。合并提交的存在意味着你和Git将会看到合并已经把合并的所有好的部分都拿走了即使合并 已经采取了所有这些部分,你将永远不会再拿走它们:所以 -s我们的允许你杀死一个分支,而不是仅仅忽略它,而是通过记录你故意杀死它的所有历史记录。



Git只记录结果,而不是记录方法



Git 不会记录合并策略,也不记录任何策略选项。所以你可以判断是否有人使用这种选择的唯一方法是猜测。如果你遇到一些仓库里面有一些合并提交,你可以自己重复合并,看看你是否得到了相同的结果。如果 do 获得相同的结果,那么合并的人可能会使用与您刚刚使用的完全相同的命令。如果你得到一个不同的结果,或许合并的人使用了不同的命令或者一组不同的参数。或者他们可以手动解决任何冲突!



更多背景



更多背景信息,
$ b




高级视图(高级视图)合并



合并的目标很容易理解。几个人或团体,或者甚至只有一个人有两个或更多的任务,从一个共同的代码库开始,并做出一系列变更。例如,在有袋动物制造商中,爱丽丝可能在制作袋熊,而鲍勃则在袋鼠上工作。每个人或团队(或者甚至只有一个人担任多个角色)都在她或他的私人存储库和/或私人分支中工作。这两条发展路线 - 即我们在第一章中提到的哲学意义上的分支 - 与这个共同的起点有关。我们并不担心他们如何管理他们的提交,但是在某个时候,某人 - 也许是Alice或Bob,或者第三个人 - 将会结合这些更改。这个组合应该采取这两个变化的所有好的部分。最简单的组合方法是从同一章节执行三路合并。现在我们理解了提交图,并且有了一个关于比较较新提交与较旧提交的总体思路,现在是时候简要介绍一下Git和Mercurial如何执行合并。



两个提交和一个合并基础



在第2章中,我们简要地注意到(见第38页和第45页)任何两个提交的LCA是它们的 merge base 。在某些情况下,可能有多个合并基础,但这很少见,我们现在还不能解决。相反,我们只要注意到,根据定义,大概单合并基础不仅仅是其他两个提交的共同祖先。实际上,它是一个正确的共同起点:它是可以从两个头(Mercurial)或分支提示(Git)中获得的第一个提交我们正在合并。 VCS需要找到合并基础,以找出我们做了什么他们做了什么。



在无论是Git还是Mercurial,我们都会在正常结帐过程中选择我们的两个提交中的一个。无论我们现在签出什么提交 - 我们的当前提交 - 参与合并。我们选择使用一些适当的提交标识符进行第二次提交,通常是分支名称,但偶尔还会有一个哈希ID,或者在Mercurial中,
a是简单的修订版本号(有时甚至一点都没有,而
则由VCS计算)为我们)。我们可以简单地运行 git merge otherbranch
hg merge otherbranch






18 我打电话这三个提交 base 当前其他。 Git对于当前和其他提交没有单一的一致名称。 Mercurial始终将它们称为 local 其他提交。我还将两个非基础提交作为合并的。在几个地方,Git会调用当前的提交我们和其他提交他们的
然而,我们将在稍后看到的我们/他们的术语中存在一个问题,那就是当我们进行采摘和重新装订时。

I am practising GIT. Whats the difference between below commands?

git merge -s ours branch

git merge -s theirs branch

git merge -X ours branch

git merge -X theirs branch

解决方案

Before I start this answer, let me emphasize that there are two different words that are both spelled "merge". There is a verb form, to merge, which means "to combine changes". There is a noun or adjective form, a merge or a merge commit, which refers to a specific kind of commit.

The git merge command usually does both: it merges (verb) some changes, and then makes a merge (noun) or a merge commit (adjective). Git has many ways to do the verb form of merge, though. It also allows the git merge command to omit the final noun form merge (but we'll ignore this case entirely here).

Strategy or extended option—the short version

The short version is that you almost never want the strategy option -s ours.

Using the -X (eXtended) options, you can tell Git to favor the "ours" or "theirs" side of a merge in the case of a conflict. That is, suppose the merge base version of file wallaby.txt says, in part:

The Bennett's wallaby is
a variety of the red-necked wallaby.

One of the two branch tip versions—let's call this the left side or local or --ours version—says:

The Bennett's wallaby is
a smaller variety of the red-necked wallaby.

The other branch tip version, i.e., the right side or remote or other or --theirs version—says:

The Bennett's wallaby,
which is found on Tasmania,
is a variety of the red-necked wallaby.

When we compare the base version to the two branch tips, the comparisons make similar, but not exactly the same, changes to the same range of lines:

$ git diff $base $left
...
 The Bennett's wallaby is
-a variety of the red-necked wallaby.
+a smaller variety of the red-necked wallaby.
...

But:

$ git diff $base $right
...
-The Bennett's wallaby is
-a variety of the red-necked wallaby.
+The Bennett's wallaby,
+which is found on Tasmania,
+is a variety of the red-necked wallaby.

These two changes clash, and you will get a merge conflict.

The eXtended -X ours option means "prefer our change": where the two changes clash, ignore their change entirely, and take ours instead. The eXtended -X theirs option means "prefer their change", i.e., ignore ours.

Note that whichever change you prefer, you will lose something here. One change mentions that the Bennett's wallaby is a bit smaller, and other other mentions that it's the Tasmanian form. If you pick just one, you lose the other. You probably should combine this change manually, rather than letting Git choose one side.

When and why you might use -s ours

If this is the only change to the file, using -s ours instead of -X ours would not make a difference to this particular file-level merge: either way we would take "our" (left-side) change, and ignore theirs. But suppose further that only their version fixes a typo elsewhere in the file:

 $ git diff $base $right
 ...
 -walaby
 +wallaby
 ...

with nothing like that in the $left (local or --ours) output. If we use -X ours instead of -s ours, we will at least pick up this fix. Of course, the right side might have a change that adds typos instead of removing them. Git won't know or care: its job is to combine the changes, not to decide whether they make any sense, whether individually or combined!

Moreover, as Tim Beigeleisen mentioned in a comment above, the -s ours option does not even look at the right-hand side diff. In fact, it does not run any diffs at all! It tells Git to make the merge commit without using the other side in any way. In other words, it merely records that there was a merge, without actually doing any merging.

The only reason to do this is to make a commit-graph history record of the merge. It is this history, as recorded in the commit graph itself, that determines how you and Git will "see" what happened, when you—or anyone else—come back later to look. The presence of a merge commit means that you and Git will see the merge as having already taken all the good parts of whatever got merged—even if the method of "taking" was ignore everything. Having already taken all those parts, you will never take them again: so -s ours allows you to "kill off" a branch, not by merely ignoring it, but by recording for all history that you deliberately killed it.

Git records only the result, not the method

Git does not record the merge strategy, nor any strategy options. So the only way you can tell whether someone used such options is to guess. If you come across some repository with some merge commits inside it, you can repeat the merges yourself, and see if you get the same result. If you do get the same result, perhaps the person who did the merge used the exact same command you just used. If you get a different result, perhaps the person who did the merge used a different command, or a different set of arguments. Or maybe they resolved any conflicts manually!

More background

For more background, let me quote from my perennially-not-making-much-progress (because I have a job :-) ) book.


A high level view of merging

The goal of a merge is easy to understand. Several people or groups, or even just one person with two or more tasks, started from a common code base, and made a series of changes. For instance, in the Marsupial Maker, Alice may be working on wombats while Bob works on kangaroos. Each person or group (or even just one person taking on multiple roles) works in her or his private repository and/or private branch. These two lines of development—i.e., branches in the philosophical sense we noted in Chapter 1—are related by this common starting point. We won’t worry yet how they manage to share their commits, but at some point, someone—perhaps Alice or Bob, or perhaps a third person—will combine the changes. The combination should take all the good parts of both changes. The simplest method of combining is to perform the three-way merge from the same chapter. Now that we understand commit graphs, and have a general idea about comparing newer commits against older ones, it is time to take a brief high level look at how both Git and Mercurial perform merges.

Two commits and a merge base

In Chapter 2, we noted briefly (see page 38 and page 45) that the LCA of any two commits is their merge base. In some cases, there can be more than one merge base, but this is rare and we won’t address it yet. Instead, let’s just note that the—presumably single—merge base is, by definition, not just a common ancestor of two other commits. It is, in fact, the correct common starting point: it is the first commit that is reachable from both of the two heads (Mercurial) or branch tips (Git) that we are merging. The VCS needs to find the merge base to find out both what we did and what they did.

In both Git and Mercurial, we choose one of our two commits by the normal checkout process. Whatever commit we have checked out now—our current commit—participates in the merge. We choose a second commit using some appropriate commit-identifier, typically a branch name but occasionally a hash ID, or in Mercurial, a simple revision number (or sometimes even nothing at all, and the VCS figures it out for us). That will be the "other" or "theirs" commit.18 We may then simply run git merge otherbranch or hg merge otherbranch.


18I call the three commits base, current, and other here. Git has no single, consistent name for the current and other commits. Mercurial consistently calls them the local and other commits. I also refer to the two non-base commits as the sides of the merge. In several places, Git does call the current commit ours and the other commit theirs. There is, however, a problem with the ours/theirs nomenclature that we will see later, when we cover cherry-picking and rebasing.

这篇关于git之间的区别合并我们的他们的命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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