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

本文详细解析了Git中ours与theirs的概念,尤其是在合并和重新定位分支时的使用。ours通常指的是当前所在分支,而theirs指的是要合并的分支。在rebase时,角色会互换,ours指远程分支,theirs指本地分支。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文翻译自:What is the precise meaning of “ours” and “theirs” in git?

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? 将我的分支合并到另一个分支时,git中的“我们的”和“他们的”是什么意思? Both branches are "ours". 两个分支都是“我们的”。

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? “我们的”是否总是指合并开始时HEAD指向的分支? 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)? 如果是这样,那为什么不使用诸如“当前分支”之类的清晰所有格代词,而不是使用指称性模棱两可的“我们”之类的所有格代词(因为这两个分支在技术上都是我们的)?

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. 我最困惑的部分是,如果我在特定分支的.gitattributes文件中指定。 Lets say in test branch I have the following .gitattributes file: 可以说在测试分支中,我有以下.gitattributes文件:

config.xml merge=ours

Now I checkout and point HEAD to master then merge in test . 现在我结帐,将HEAD指向master,然后合并到test中 Since master is ours, and test 's .gitattributes is not checked out, will it even have an effect? 由于master是我们的主人 ,并且test的.gitattributes未检出,它甚至会起作用吗? If it does have an effect, since master is now "ours", then what will happen? 如果确实有效果,那么既然主人现在是我们的,那将会发生什么?


#1楼

参考:https://stackoom.com/question/1JjAP/git中-我们的-和-他们的-的确切含义是什么


#2楼

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. 更糟的是,当您进行基准调整时,我们/他们的整个工作切换角色(倒退)。

Ultimately, during a git merge , the "ours" branch refers to the branch you're merging into : 最终,在git merge期间,“我们的”分支是指您要合并的分支:

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 on when 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. 您通过原始提交ID合并的位置。 Worse, you can even do this: 更糟糕的是,您甚至可以执行以下操作:

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

in which case there are no branch names involved! 在这种情况下, 涉及分支名称!

I think it's little help here, but in fact, in gitrevisions syntax , 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 rebase is that rebase works by doing a series of cherry-picks, into an anonymous branch (detached HEAD mode). 在“我们”和“他们”的概念在被换周围的理由rebase是重订工作做了一系列的樱花选秀权,成为一个匿名的分支(分离的头模式)。 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". 目标分支是匿名分支,而merge-from分支是您的原始(重新设置基准)分支:因此,“-我们的”表示正在建立匿名的一个基准,而“-他们的”表示“正在重新建立我们的分支” 。


As for the gitattributes entry: it could have an effect: "ours" really means "use stage #2" internally. 至于gitattributes条目:它可能会产生影响:“我们的”实际上是在内部表示“使用阶段2”。 But as you note, it's not actually in place at the time, so it should not have an effect here ... well, not unless you copy it into the work tree before you start. 但是正如您所注意到的,它当时实际上并不存在,因此它应该不会在这里起作用……好吧,除非您在开始之前将其复制到工作树中,否则不会这样做。

Also, by the way, this applies to all uses of ours and theirs, but some are on a whole file level ( -s ours for a merge strategy; git checkout --ours during a merge conflict) and some are on a piece-by-piece basis ( -X ours or -X theirs during a -s recursive merge). 另外,顺便说一句,这适用于我们及其使用的所有用途,但是有些用途在整个文件级别( -s ours的合并策略; git checkout --ours在合并冲突期间使用),而有些则处于git checkout --ours状态-逐个基础(在-s recursive合并过程中-X ours-X theirs )。 Which probably does not help with any of the confusion. 这可能无助于解决任何混乱。

I've never come up with a better name for these, though. 不过,我从来没有想出一个更好的名字。 And: see VonC's answer to another question, where git mergetool introduces yet more names for these, calling them "local" and "remote"! 并且:请参见VonC对另一个问题的回答 ,其中git mergetool为它们引入了更多名称,称它们为“本地”和“远程”!


#3楼

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). 他们的 ”指的是保存作品以便进行基础更改(将更改重播到当前分支上)的版本。

This may appear to be swapped to people who are not aware that doing rebasing (eg 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-checkout was further clarified in Git >=2.5.1 as per f303016 commit : git-checkout的文档根据f303016 commit在Git> = 2.5.1中进一步阐明:

--ours --theirs --ours --theirs

When checking out paths from the index, check out stage #2 ('ours') or #3 ('theirs') for unmerged paths. 从索引中检出路径时,请检出第2阶段(“我们的”)或第3阶段(“ theirs”)的未合并路径。

Note that during git rebase and git pull --rebase , 'ours' and 'theirs' may appear swapped; 注意,在git rebasegit pull --rebase ,“我们的”和“他们的”可能会互换; --ours gives the version from the branch the changes are rebased onto, while --theirs gives the version from the branch that holds your work that is being rebased. --ours提供更改所基于的分支的版本,而--theirs提供保存要重新构建的工作的分支的版本。

This is because rebase is 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. 这是因为在工作流中使用了rebase ,该工作流将远程站点上的历史记录视为共享规范,并将您要重新部署的分支上完成的工作视为要集成的第三方工作,并且您暂时担当了该角色改组期间的规范历史保持者的身份。 As the keeper of the canonical history, you need to view the history from the remote as ours (ie "our shared canonical history"), while what you did on your side branch as theirs (ie "one contributor's work on top of it"). 作为规范历史的维护者,您需要从远程查看与ours一样的历史(即“我们共享的规范历史”),而您在分支机构所做的工作就是作为theirs (即“一个贡献者的工作”)。 )。

For git-merge it'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 merge and git pull commands) allows the backend merge strategies to be chosen with -s option. 合并机制( git mergegit pull命令)允许使用-s选项选择后端合并策略。 Some strategies can also take their own options, which can be passed by giving -X<option> arguments to git merge and/or git pull . 一些策略也可以采用自己的选项,可以通过为git merge和/或git pull提供-X<option>参数来传递它们。


So sometimes it can be confusing, for example: 因此有时可能会令人困惑,例如:

  • git pull origin master where -Xours is our local, -Xtheirs is theirs (remote) branch git pull origin master ,其中-Xours是我们的本地, -Xtheirs是他们的(远程)分支
  • git pull origin master -r where -Xours is theirs (remote), -Xtheirs is ours 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 merge strategies ( -X ours and -X theirs ). git merge策略相似( -X ours-X theirs )。


#4楼

  • 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.5 and you merge branch feature/new-buttons into it, then the content as found in release/2.5 is what ours refers to and the content as found on feature/new-buttons is what theirs refers to. 因此,如果您使用的是分支版本/2.5,并且将分支功能/新按钮合并到其中,那么发布 /2.5中的内容就是我们所指的内容,而功能/新按钮上的内容就是他们所指的内容至。 During a merge action this is pretty straight forward. 在合并操作期间,这非常简单。

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: 考虑重新设计工作,像这样:

  1. All commits you have done since your last pull are moved to a branch of their own, let's name it BranchX . 自上次拉取以来,您所做的所有提交都移到了自己的分支中,我们将其命名为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 BranchX is cherry-picked in order old to new to your current branch. 现在, BranchX上的每个提交都是精心挑选的,以便从旧到新到当前分支。
  4. BranchX is deleted again and thus won't ever show up in any history. 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. 如果您查看2和3,您将了解为什么现在要互换角色。 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). 从2开始,您当前的分支现在是服务器的分支,无需进行任何更改,因此这就是我们的分支(您所在的分支)。 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). 您所做的更改现在位于当前分支( 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始终选择“他们的”。


#5楼

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) (当然,这是完整的文件)


#6楼

From git checkout 's usage: git 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_file to reset the file to the current version and the incoming versions respectively. 解决合并冲突时,可以执行git checkout --theirs some_filegit checkout --ours some_file将文件分别重置为当前版本和传入版本。

If you've done git checkout --ours some_file or git checkout --theirs some_file and 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并想将文件重置为文件的三向合并版本,则可以执行git checkout --merge some_file

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值