将我的分支合并到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
为其引入了更多名称,称它们为“本地”和“远程”!#2 楼
Git中的“我们的”是指原始工作分支,它在git历史中具有权威性/规范性的部分。“他们的”是指保留该作品以便进行重新定位的版本(更改可以重播到当前分支上。
这似乎交换给了那些不知道进行重定基(例如
git rebase
)实际上使您的工作(保持他们的工作)的人重播属于我们的规范/主要历史记录,因为我们将更改作为第三方工作的基础。git-checkout
的文档在Git> = 2.5.1中得到了进一步澄清,如f303016
提交:--ours
--theirs
从索引中检出路径时,检出阶段#2
(“我们的”)
请注意,在
git rebase
和git pull --rebase
期间,“我们的”和“他们的”可能会互换。 --ours
提供了更改所基于的分支的版本,而--theirs
提供了要保存要进行基础更改的分支的版本。这是因为
rebase
用于处理远程的历史记录作为共享的规范规范,将您要重新部署的分支机构上完成的工作视为要集成的第三方工作,并且您暂时在改编过程中承担规范历史的保持者的角色。作为规范历史的保存者,您需要从远程以ours
(即“我们共享的规范历史”)查看历史,而在分支机构上以theirs
(即“一个贡献者的工作”)来查看历史。 )。对于
git-merge
的解释如下:我们的
通过支持我们的版本,该选项可以强制自动解决冲突的大块。与其他树不冲突的更改将反映到合并结果中。对于二进制文件,全部内容都是从我们这边获取的。
这不应与我们的合并策略混淆,该策略甚至根本不会查看另一棵树包含的内容。它丢弃另一棵树所做的所有操作,声明我们的历史包含其中发生的所有事件。
他们的
这与我们的相反。
此外,这里说明了如何使用它们:
合并机制(
git merge
和git 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_file
和git checkout --ours some_file
分别将文件重置为当前版本和传入版本。 如果您已完成
git checkout --ours some_file
或git 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
评论
+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