这听起来像是一个问题的基本知识,但是我已经寻找了答案,现在我比以前更加困惑。

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

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

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

还是只使用分支名称(而不是说“我们的”,而只是说“本地主人的”之类的话)?

对我来说最令人困惑的部分是如果我在特定分支的.gitattributes文件。可以说在测试分支中,我有以下.gitattributes文件:

config.xml merge=ours


现在我结帐并将HEAD指向master,然后合并到测试中。由于master是我们的,并且test的.gitattributes没有检出,它甚至会起作用吗?如果确实有效果,那么既然主人现在是“我们的”,那么会发生什么?

#1 楼

我怀疑您在这里感到困惑,因为这从根本上是令人困惑的。更糟的是,当您进行基准调整时,我们/他们的整个工作切换角色(倒退)。

最终,在git merge期间,“我们的”分支是指您所在的分支合并到:

git checkout merge-into-ours


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

git merge from-theirs


,这里的“我们的”和“他们的”是有意义的,即使“他们的”可能仍然是您的,但“他们的”却不是您在运行git merge时使用的那个。

虽然使用实际的分支名称可能很酷,但在更复杂的情况下却会分崩离析。例如,代替上面的操作,您可以这样做:

git checkout ours
git merge 1234567


,其中您通过原始提交ID进行合并。更糟糕的是,您甚至可以执行以下操作:

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


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

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

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


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


“我们的”和“他们的”概念被交换的原因在rebase期间,周围的环境是通过执行一系列的插接操作将rebase工作到匿名分支(分离的HEAD模式)中。目标分支是匿名分支,而merge-from分支是您原始的(重新设置基准)分支:因此,“-我们的”表示正在建立匿名的一个基准,而“-他们的”表示“正在重新建立我们的分支” ..


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

另外,顺便说一句,这适用于我们及其使用的所有用途,但有些使用在整个文件级别(-s ours用于合并策略; git checkout --ours在合并冲突期间),而某些则是逐段使用(-X ours或在-X theirs合并期间插入-s recursive)。但这可能无助于解决任何混乱。

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

评论


+1。关于我们及其在重新定级期间将被撤消的信息,另请参阅:stackoverflow.com/a/2960751/6309和stackoverflow.com/a/3052118/6309

–VonC
14年8月29日在22:01

两件事相互“融合”。合并时,双方会相互“合并”。我认为说双方之一“没有合并成任何东西”是不正确的。如果不涉及分支名称(如您所指出的),则涉及提交名称(您可以说“ 7777777's”和“ 1234567's”,而不是“ ours”和“ theirs”)。我了解在调整基准期间会发生什么,而且我完全没有觉得这会造成混淆。我认为“ HEAD”和“传入”将比“我们的”和“他们的”更好,因为总有一个“ HEAD”(无论是否分离)。

– ComaToast
2014年8月29日在22:18

我猜想,因为头部是思想的源泉,是身份的源泉,是自我的源泉,所以思考一下HEAD所指的“我的”(“我们的”,我猜我和HEAD有两个)。如果仅此而已,那将只是一个不错的助记符设备。

– ComaToast
2014年8月29日在22:20

话虽这么说,我仍然喜欢在做诸如变基……之类的事情之前,先对整个回购进行物理复制。

– ComaToast
2015年11月17日下午6:11

“在这种情况下,不涉及分支名称!” ...因此,应改用commit comment / hash。不管它能得到什么。实际上,任何事情都比“我们的”和“他们的”好。我不知道这种困惑已经消失了数千个开发小时。 git对C ++的“最烦人的解析”的回答;)

–贾罗德·史密斯(Jarrod Smith)
18年5月2日,0:44



#2 楼

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

“他们的”是指保留该作品以便进行重新定位的版本(更改可以重播到当前分支上。

这似乎交换给了那些不知道进行重定基(例如git rebase)实际上使您的工作(保持他们的工作)的人重播属于我们的规范/主要历史记录,因为我们将更改作为第三方工作的基础。

git-checkout的文档在Git> = 2.5.1中得到了进一步澄清,如f303016提交:


--ours
--theirs

从索引中检出路径时,检出阶段#2
(“我们的”)

请注意,在git rebasegit pull --rebase期间,“我们的”和“他们的”可能会互换。 --ours提供了更改所基于的分支的版本,而--theirs提供了要保存要进行基础更改的分支的版本。

这是因为rebase用于处理远程的历史记录作为共享的规范规范,将您要重新部署的分支机构上完成的工作视为要集成的第三方工作,并且您暂时在改编过程中承担规范历史的保持者的角色。作为规范历史的保存者,您需要从远程以ours(即“我们共享的规范历史”)查看历史,而在分支机构上以theirs(即“一个贡献者的工作”)来查看历史。 )。


对于git-merge的解释如下:


我们的

通过支持我们的版本,该选项可以强制自动解决冲突的大块。与其他树不冲突的更改将反映到合并结果中。对于二进制文件,全部内容都是从我们这边获取的。

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

他们的

这与我们的相反。


此外,这里说明了如何使用它们:


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



因此有时可能令人困惑,例如:



git pull origin master其中-Xours是我们的本地分支,-Xtheirs是他们的(远程)分支

git pull origin master -r其中-Xours是他们的(远程),-Xtheirs是我们的

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

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

评论


这个答案似乎已经过时=>“ git merge --ours”不是有效的选项

–亚历山大·米尔斯(Alexander Mills)
16-10-23在5:21

@AlexanderMills答案没有提到git merge,但是以git pull和git checkout为例。如果您想将此参数与git merge一起使用,则应使用-X ours。您仍然可以使用--ours语法进行git checkout。我已经进一步澄清了答案。

– Kenorb
16-10-23在12:59



您对变基方式的解释是向后的,我可能会记得没有谷歌搜索的情况。谢谢!

–道格
20/11/11在18:09

#3 楼

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

这里是基础知识:

合并:

$ git checkout master 
$ git merge feature


如果要在master中选择版本:

$ git checkout --ours codefile.js


如果要在feature中选择版本:

$ git checkout --theirs codefile.js



$ git checkout feature 
$ git rebase master 


如果要在master中选择版本:

$ git checkout --ours codefile.js


如果要在feature中选择版本:

$ git checkout --theirs codefile.js


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

评论


该网站非常有帮助。流程图样式和颜色编码的单词使网站比SO答案更易于理解。谢谢。

–罗恩
20-3-31的1:01

谢谢,这是我一直在寻找的简单示例说明。其他答案太多地谈论了为什么您可能会感到困惑,以及术语的含义等等,以至于答案变得令人困惑。

–达里奥·塞德尔(Dario Seidl)
20 Dec 3'at 12:42

#4 楼



我们的:这是您当前所在的分支。

他们的:这是您的操作中使用的另一个分支。

所以如果您使用的是分支版本/2.5,并且将分支功能/新按钮合并到其中,那么发布/2.5中的内容就是我们所指的内容,而功能/新按钮上的内容就是他们所指的内容。 。在合并操作期间,这非常简单。

大多数人唯一想到的问题是重新设置基准。如果执行重新基准而不是常规合并,则会交换角色。怎么样?好吧,这完全是由重新定基的方式引起的。考虑将rebase像这样工作:


自上次拉取以来所做的所有提交都移到了自己的分支中,我们将其命名为BranchX。
您签出了当前分支的负责人,放弃您所做的任何本地
更改,但是那样检索其他人为该分支推送的所有更改。
现在,对BranchX的每次提交都经过精心挑选,以便按照从旧到新的顺序进行操作分支。

BranchX再次被删除,因此永远不会出现在任何历史记录中。

当然,这不是真正的事情,但这是一个不错的思维模型为了我。而且,如果您查看2和3,您将了解为什么现在要互换角色。从2开始,您当前的分支现在是服务器的分支,无需进行任何更改,因此这就是我们的分支(您所在的分支)。您所做的更改现在位于当前分支(BranchX)以外的其他分支上,因此这些更改(尽管是您所做的更改)是它们的分支(您的操作中使用的另一个分支)。

这意味着,如果您合并并且希望您的更改始终获胜,则会告诉git始终选择“我们的”,但是如果您重新定基并且希望所有更改都始终获胜,则会告诉git始终选择“他们的”。

#5 楼

我知道它并不能解释其含义,但是我为自己制作了一个小图像,以提醒您使用哪个图像:



希望有帮助!

PS-也请检查Nitay答案中的链接🙂

评论


我花了很长时间阅读其中一些答案的书,尽管您的形象虽然不完美,但以一种更为简洁的方式对我来说几乎完美。在这种情况下,第2版可以直观地使用“ HEAD”一词的解释

–David van Dugteren
20年7月6日,下午3:47

Tnx的赞美!我很高兴它在视觉上帮助了我,并帮助了其他人!我省略了HEAD,因为它是与时间相关的信息,它是特定时间点的指针。对于图像,我想给出“永恒”的视图;尽管我认为掌握git新手并不明显。为了解释/显示HEAD,我需要为每个git ..命令显示一个(结帐后,合并后,变基之后);恕我直言,这可能会导致图像更加混乱;因此,我理所当然地认为一个人已经具有历史,HEAD,结帐,合并和变基的知识/概念。

–卡马羽
20-10-1在13:34



#6 楼

我将在这里张贴我的备忘录,因为我不得不一次又一次回到这里。
场景1.普通开发人员:您是不能合并到master的开发人员,只需要使用feature分支即可。feature分支(=重新设置为master),因为master包含新的依赖关系更新,并且您想覆盖您的适度更改。
git checkout master
git pull

git checkout feature
git rebase -X ours master
feature分支重新设置为master更改。但是,您做得比同事更多,并且想优先使用自己的更改。
git checkout master
git pull

git checkout feature
git rebase -X theirs master

重要提示:正如您所看到的那样,普通开发人员应该更喜欢rebase并每天早晨像练习/咖啡一样重复。
场景2.合并感官:您是团队负责人,想合并其他分支并将合并后的结果直接推送给主管。 master是您将要更改的分支。
案例1:主宰是国王您想合并第三方分支,但master是优先事项。 feature是您上级所做的一个分支。
git checkout feature
git pull

git checkout master
git merge -X ours feature

案例2:新变化为王当您的高级开发人员发布了一个不错的feature,并且您想覆盖master分支中的旧版本时。
git checkout feature
git pull

git checkout master
git merge -X theirs feature

记住:在午夜记得选择哪个:master总是ours。而theirs是他们所做的feature

评论


注意:-X表示--strategy-option并允许偏爱他们或我们的代码

–卡马羽
20年7月8日在12:25



#7 楼

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

如果您已完成git checkout --ours some_filegit checkout --theirs some_file并想将文件重置为文件的三向合并版本,则可以执行git checkout --merge some_file

#8 楼

没有确切的含义,正是因为这些术语的含义相反,这取决于您是合并还是重新定基。思考两个分支的自然方法是“我的工作”和“别人的工作”。混淆这种分类的术语选择绝对是git中最糟糕的设计选择。它一定是受到会计的“贷方”和“借方”或“资产”和“负债”的启发-同样令人头疼。

评论


我要不同的是,有一个精确的含义:“我们的”是指“ HEAD在哪里”,在合并或变基中:stackoverflow.com/a/2960751/6309

–VonC
20-10-11在19:54



“ HEAD在哪里”是以工具为中心而不是以用户为中心的概念。这就是问题所在。

– SzczepanHołyszewski
20-10-11在20:01

我现在看到你的观点。您是正确的,尽管从这个角度(工具还是用户)来看,确实存在许多可疑的设计决策。有些正在改善:想到git checkout与git switch / git restore。

–VonC
20-10-11在20:07