git git中“我们的”和“他们的”的确切含义是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25576415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 02:24:25  来源:igfitidea点击:

What is the precise meaning of "ours" and "theirs" in git?

gitmerge

提问by CommaToast

This might sound like too basic of a question, but I have searched for answers and I am more confused now than before.

这听起来可能是一个太基本的问题,但我已经搜索了答案,现在我比以前更加困惑。

What does "ours" and "theirs" mean in git when merging my branch into my other branch? Both branches are "ours".

将我的分支合并到另一个分支时,git 中的“我们的”和“他们的”是什么意思?两个分支都是“我们的”。

In a merge conflict is "ours" always the upper of the two versions displayed?

在合并冲突中,“我们的”总是显示的两个版本中的上一个吗?

Does "ours" always refer to the branch that HEAD was pointing to when the merge began? If so then why not use a clear possessive reference like "current branch's" instead of using a possessive pronoun like "ours" that is referentially ambiguous (since both branches are technically ours)?

“ours”是否总是指合并开始时 HEAD 指向的分支?如果是这样,那么为什么不使用像“current branch's”这样的明确的所有格引用,而不是使用像“ours”这样的所有格代词,它在指称上是模棱两可的(因为两个分支在技术上都是我们的)?

Or just use the branch name (instead of saying "ours" just say "local master's" or such)?

或者只是使用分支名称(而不是说“我们的”,而只是说“本地大师的”之类的)?

The most confusing part to me is if I specify in a specific branch's .gitattributes file. Lets say in test branchI have the following .gitattributes file:

对我来说最令人困惑的部分是我是否在特定分支的 .gitattributes 文件中指定。让我们说在测试分支我有以下 .gitattributes 文件:

config.xml merge=ours

Now I checkout and point HEAD to masterthen merge in test. Since masteris ours, and test's .gitattributes is not checked out, will it even have an effect? If it does have an effect, since masteris now "ours", then what will happen?

现在我结帐并将 HEAD 指向master然后合并到test。既然master是我们的,而test的 .gitattributes 没有检出,它甚至会产生影响吗?如果真的有效果,既然师父现在是“我们的”,那会发生什么?

回答by torek

I suspect you're confused here because it's fundamentally confusing. To make things worse, the whole ours/theirs stuff switches roles (becomes backwards) when you are doing a rebase.

我怀疑您在这里感到困惑,因为它从根本上令人困惑。更糟糕的是,当您进行 rebase 时,整个我们/他们的东西都会转换角色(变得倒退)。

Ultimately, during a git merge, the "ours" branch refers to the branch you're merging into:

最终,在 a 期间git merge,“ours”分支指的是您要合并的分支:

git checkout merge-into-ours

and the "theirs" branch refers to the (single) branch you're merging:

并且“他们的”分支指的是您要合并的(单个)分支:

git merge from-theirs

and here "ours" and "theirs" makes some sense, as even though "theirs" is probably yours anyway, "theirs" is not the one you were onwhen you ran git merge.

这里“我们”和“他们”有一定道理,因为,即使“他们”可能是你的,无论如何,“他们”是不是你是我的唯一,当你跑了git merge

While using the actual branch name might be pretty cool, it falls apart in more complex cases. For instance, instead of the above, you might do:

虽然使用实际的分支名称可能很酷,但在更复杂的情况下它会崩溃。例如,您可以执行以下操作,而不是:

git checkout ours
git merge 1234567

where you're merging by raw commit-ID. Worse, you can even do this:

您正在通过原始提交 ID 合并的位置。更糟糕的是,您甚至可以这样做:

git checkout 7777777    # detach HEAD
git merge 1234567       # do a test merge

in which case there are nobranch names involved!

在这种情况下,涉及分支名称!

I think it's little help here, but in fact, in gitrevisionssyntax, you can refer to an individual path in the index by number, during a conflicted merge

我认为这在这里没什么帮助,但实际上,在gitrevisions语法上,您可以在冲突合并期间按编号引用索引中的单个路径

git show :1:README
git show :2:README
git show :3:README

Stage #1 is the common ancestor of the files, stage #2 is the target-branch version, and stage #3 is the version you are merging from.

第 1 阶段是文件的共同祖先,第 2 阶段是目标分支版本,第 3 阶段是您从中合并的版本。



The reason the "ours" and "theirs" notions get swapped around during rebaseis that rebase works by doing a series of cherry-picks, into an anonymous branch (detached HEAD mode). The target branch is the anonymous branch, and the merge-from branch is your original (pre-rebase) branch: so "--ours" means the anonymous one rebase is building while "--theirs" means "our branch being rebased".

“我们的”和“他们的”概念在此期间rebase被交换的原因是 rebase 通过对匿名分支(分离的 HEAD 模式)进行一系列挑选来工作。目标分支是匿名分支,merge-from 分支是你原来的(re-rebase 前)分支:所以“--ours”意味着匿名一个 rebase 正在构建,而“--theirs”意味着“我们的分支正在rebase” .



As for the gitattributes entry: it couldhave an effect: "ours" really means "use stage #2" internally. But as you note, it's not actually in place at the time, so it should nothave an effect here ... well, not unless you copy it into the work tree before you start.

至于 gitattributes 条目:它可能会产生影响:“我们的”在内部实际上意味着“使用第 2 阶段”。但正如您所注意到的,它当时实际上并没有到位,所以它不应该在这里产生影响……好吧,除非您在开始之前将其复制到工作树中,否则不会产生影响。

Also, by the way, this applies to all uses of ours and theirs, but some are on a whole file level (-s oursfor a merge strategy; git checkout --oursduring a merge conflict) and some are on a piece-by-piece basis (-X oursor -X theirsduring a -s recursivemerge). Which probably does not help with any of the confusion.

此外,顺便说一下,这适用于我们和他们的所有用途,但有些是在整个文件级别(-s ours对于合并策略;git checkout --ours在合并冲突期间),有些是逐个的(-X ours-X theirs在合并冲突期间)-s recursive合并)。这可能无助于任何混乱。

I've never come up with a better name for these, though. And: see VonC's answerto another question, where git mergetoolintroduces yet more names for these, calling them "local" and "remote"!

不过,我从来没有想出更好的名字。并且:请参阅VonC对另一个问题的回答,其中git mergetool介绍了更多名称,称它们为“本地”和“远程”!

回答by kenorb

The 'ours' in Git is referring to the original working branch which has authoritative/canonical part of git history.

Git 中的“我们的”指的是原始工作分支,它具有 git 历史的权威/规范部分。

The 'theirs' refers to the version that holds the work in order to be rebased(changes to be replayed onto the current branch).

' theirs' 是指保存工作以便重新定位的版本(更改要重播到当前分支)。

This may appear to be swapped to people who are not aware that doing rebasing (e.g. git rebase) is actually taking your work on hold (which is theirs) in order to replay onto the canonical/main history which is ours, because we're rebasing our changes as third-party work.

这似乎被交换给了那些不知道进行重新定位(例如git rebase)实际上是在暂停您的工作(这是他们的工作)以重播我们的规范/主要历史的人,因为我们正在重新调整我们的更改为第三方工作。

The documentation for git-checkoutwas further clarified in Git >=2.5.1 as per f303016commit:

为文档git-checkout在GIT中被进一步澄清> = 2.5.1按f303016提交

--ours--theirs

When checking out paths from the index, check out stage #2 ('ours') or #3 ('theirs') for unmerged paths.

Note that during git rebaseand git pull --rebase, 'ours' and 'theirs' may appear swapped; --oursgives the version from the branch the changes are rebased onto, while --theirsgives the version from the branch that holds your work that is being rebased.

This is because rebaseis used in a workflow that treats the history at the remote as the shared canonical one, and treats the work done on the branch you are rebasing as the third-party work to be integrated, and you are temporarily assuming the role of the keeper of the canonical history during the rebase. As the keeper of the canonical history, you need to view the history from the remote as ours(i.e. "our shared canonical history"), while what you did on your side branch as theirs(i.e. "one contributor's work on top of it").

--ours--theirs

从索引中检查路径时,请检查第 2 阶段(“我们的”)或第 3 阶段(“他们的”)以获取未合并的路径。

请注意,在git rebaseand期间git pull --rebase,“我们的”和“他们的”可能会出现交换;--ours给出更改被重新定位到--theirs的分支的版本,同时给出保存正在重新定位的工作的分支的版本。

这是因为rebase用于将远程历史作为共享规范的工作流,并将在您正在变基的分支上完成的工作视为要集成的第三方工作,并且您暂时担任变基期间规范历史的保管人。作为规范历史的守护者,您需要将远程历史视为ours(即“我们共享的规范历史”),而您在侧分支上所做的则为theirs(即“一个贡献者在其上的工作”)。

For git-mergeit's explain in the following way:

因为git-merge它的解释如下:

ours

This option forces conflicting hunks to be auto-resolved cleanly by favoring our version. Changes from the other tree that do not conflict with our side are reflected to the merge result. For a binary file, the entire contents are taken from our side.

This should not be confused with the ours merge strategy, which does not even look at what the other tree contains at all. It discards everything the other tree did, declaring our history contains all that happened in it.

theirs

This is the opposite of ours.

我们的

此选项通过支持我们的版本强制自动解决冲突的大块头。来自另一棵树的与我们这边不冲突的变化会反映到合并结果中。对于二进制文件,所有内容都取自我们这边。

这不应与我们的合并策略混淆,后者甚至根本不查看其他树包含的内容。它丢弃另一棵树所做的一切,声明我们的历史包含其中发生的所有事情。

他们的

这与我们相反。

Further more, here is explained how to use them:

此外,这里解释了如何使用它们:

The merge mechanism (git mergeand git pullcommands) allows the backend merge strategies to be chosen with -soption. Some strategies can also take their own options, which can be passed by giving -X<option>arguments to git mergeand/or git pull.

合并机制(git mergegit pull命令)允许使用-s选项选择后端合并策略。一些策略也可以采用自己的选项,可以通过给和/或提供-X<option>参数来传递。git mergegit pull



So sometimes it can be confusing, for example:

所以有时它可能会令人困惑,例如:

  • git pull origin masterwhere -Xoursis our local, -Xtheirsis theirs (remote) branch
  • git pull origin master -rwhere -Xoursis theirs (remote), -Xtheirsis ours
  • git pull origin master-Xours我们的本地在哪里,-Xtheirs他们的(远程)分支机构在哪里
  • git pull origin master -r-Xours他们的(远程)在哪里,-Xtheirs是我们的

So the 2nd example is opposite to the 1st one, because we're rebasing our branch on top of the remote one, so our starting point is remote one, and our changes are treated as external.

所以第二个例子与第一个相反,因为我们将我们的分支重新建立在远程分支之上,所以我们的起点是远程分支,我们的更改被视为外部。

Similar for git mergestrategies (-X oursand -X theirs).

类似的git merge策略(-X ours-X theirs)。

回答by Nitay

I know this has been answered, but this issue confused me so many times I've put up a small reference website to help me remember: https://nitaym.github.io/ourstheirs/

我知道这已经得到了回答,但是这个问题让我困惑了很多次我已经建立了一个小型参考网站来帮助我记住:https: //nitaym.github.io/ourstheirs/

Here are the basics:

以下是基础知识:

Merges:

合并:

$ git checkout master 
$ git merge feature

If you want to select the version in master:

如果要选择 中的版本master

$ git checkout --ours codefile.js

If you want to select the version in feature:

如果要选择 中的版本feature

$ git checkout --theirs codefile.js

Rebases:

变基:

$ git checkout feature 
$ git rebase master 

If you want to select the version in master:

如果要选择 中的版本master

$ git checkout --ours codefile.js

If you want to select the version in feature:

如果要选择 中的版本feature

$ git checkout --theirs codefile.js

(This is for complete files, of course)

(当然,这是针对完整文件的)

回答by Mecki

  • Ours: This is the branch you are currently on.
  • Theirs: This is the other branch that is used in your action.
  • 我们的:这是您目前所在的分行。
  • 他们的:这是您的操作中使用的另一个分支。

So if you are on branch release/2.5and you merge branch feature/new-buttonsinto it, then the content as found in release/2.5is what oursrefers to and the content as found on feature/new-buttonsis what theirsrefers to. During a merge action this is pretty straight forward.

因此,如果您在分支release/2.5 上并将分支feature/new-buttons合并到其中,那么在release/2.5 中找到的内容就是我们所指的内容,而在feature/new-buttons上找到的内容就是他们所指的内容到。在合并操作期间,这非常简单。

The only problem most people fall for is the rebase case. If you do a re-base instead of a normal merge, the roles are swapped. How's that? Well, that's caused solely by the way rebasing works. Think of rebase to work like that:

大多数人陷入的唯一问题是rebase 案例。如果您执行重新设置而不是正常合并,则角色会交换。怎么样?嗯,这完全是由变基的工作方式引起的。想想 rebase 像这样工作:

  1. All commits you have done since your last pull are moved to a branch of their own, let's name it BranchX.
  2. You checkout the head of your current branch, discarding any local changes you had but that way retrieving all changes others have pushed for that branch.
  3. Now every commit on BranchXis cherry-picked in order old to new to your current branch.
  4. BranchXis deleted again and thus won't ever show up in any history.
  1. 自上次拉取以来您所做的所有提交都将移动到它们自己的分支中,我们将其命名为BranchX
  2. 您签出当前分支的头,丢弃您拥有的任何本地更改,但这样检索其他人为该分支推送的所有更改。
  3. 现在,BranchX上的每个提交都经过精心挑选,以便从旧到新到您当前的分支。
  4. BranchX再次被删除,因此永远不会出现在任何历史记录中。

Of course, that's not really what is going on but it's a nice mind model for me. And if you look at 2 and 3, you will understand why the roles are swapped now. As of 2, your current branch is now the branch from the server without any of your changes, so this is ours(the branch you are on). The changes you made are now on a different branch that is not your current one (BranchX) and thus these changes (despite being the changes you made) are theirs(the other branch used in your action).

当然,这并不是真正发生的事情,但对我来说这是一个很好的思维模型。如果你看看 2 和 3,你就会明白为什么现在角色互换了。从 2 开始,您当前的分支现在是来自服务器的分支,没有您的任何更改,所以这是我们的(您所在的分支)。您所做的更改现在位于不同的分支上,而不是您当前的分支 ( BranchX),因此这些更改(尽管是您所做的更改)是他们的(您的操作中使用的另一个分支)。

That means if you merge and you want your changes to always win, you'd tell git to always choose "ours" but if you rebase and you want all your changes to always win, you tell git to always choose "theirs".

这意味着如果你合并并且你希望你的更改总是获胜,你会告诉 git 总是选择“我们的”但是如果你变基并且你希望你的所有更改总是获胜,你告诉 git 总是选择“他们的”。

回答by Kamafeather

I know it doesn't explain the meaning but I've made myself a little image, as reference to remind which one to use:

我知道它没有解释含义,但我给自己做了一个小图像,作为参考以提醒使用哪个:

enter image description here

在此处输入图片说明

Hope it helps!

希望能帮助到你!

PS - Give a check also to the link in Nitay's answer

PS - 还要检查Nitay 答案中的链接

回答by DenisKolodin

I'll post my memo here, because I have to come back here again and again.

我会把我的备忘录贴在这里,因为我必须一次又一次地回到这里。

SCENARIO 1. Normal developer:You are developer who can't merge to masterand have to play with featurebranches only.

SCENARIO 1.普通开发者:你是不能合并的开发者,只能masterfeature分支。

Case 1: master is a king.You want to refresh your featurebranch (= rebase to master), because mastercontains new updates of dependencies and you want to overwrite your modest changes.

案例一:主人为王。您想刷新您的feature分支(= rebase to master),因为master包含依赖项的新更新并且您想覆盖您的适度更改。

git checkout master
git pull

git checkout feature
git rebase -X ours master

Case 2: you are a king.You want to rebase your featurebranch to masterchanges. But you did more than your colleagues had and want to use your own changes in a priority.

案例2:你是国王。您希望将您的feature分支重新设置为master更改的基础。但是你做的比你的同事多,并且想优先使用你自己的改变。

git checkout master
git pull

git checkout feature
git rebase -X theirs master

IMPORTANT: As you can see normal developers should prefer rebaseand repeat it every morning like exercises/coffee.

重要提示:正如您所看到的,正常的开发人员应该喜欢rebase每天早上像练习/咖啡一样重复它。

SCENARIO 2. Merging-sensei:You are a team-lead and want to merge other branches and push a merged result directly to a master. masteris a branch you will change.

场景 2. 合并老师:您是团队负责人,想要合并其他分支并将合并的结果直接推送给 master。master是一个你会改变的分支。

Case 1: master is a kingYou want to merge third-party branch, but masteris a priority. featureis a branch that your senior did.

案例一:master为王想要合并第三方分支,但是master是一个优先级。feature是你的前辈做的一个分支。

git checkout feature
git pull

git checkout master
git merge -X ours master

Case 2: new changes is a kingWhen your senior developer released a cool featureand you want to overwrite the old s**t in the masterbranch.

案例二:新改为王当你的资深开发者发布了一个cool feature,你想覆盖master分支中的旧s**t 。

git checkout feature
git pull

git checkout master
git merge -X theirs master

REMEMBER: To remember in a midnight which one to choose: masteris oursALWAYS. And theirsis a featurethat theirs have done.

记住:要在午夜该选记得masterours始终。并且theirsfeature他们已经完成的。

回答by Joshua Ryan

From git checkout's usage:

Fromgit checkout的用法:

-2, --ours            checkout our version for unmerged files
-3, --theirs          checkout their version for unmerged files
-m, --merge           perform a 3-way merge with the new branch

When resolving merge conflicts, you can do git checkout --theirs some_file, and git checkout --ours some_fileto reset the file to the current version and the incoming versions respectively.

解决合并冲突时,您可以执行git checkout --theirs some_file, 和git checkout --ours some_file将文件分别重置为当前版本和传入版本。

If you've done git checkout --ours some_fileor git checkout --theirs some_fileand would like to reset the file to the 3-way merge version of the file, you can do git checkout --merge some_file.

如果您已经完成git checkout --ours some_filegit checkout --theirs some_file想要将文件重置为文件的 3 路合并版本,您可以执行git checkout --merge some_file.