这听起来可能是一个太基本的问题,但我一直在寻找答案,现在我比以前更困惑了。

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

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

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

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

最让我困惑的部分是,如果我在一个特定分支的.gitattributes文件中指定。让我们说在测试分支中,我有以下.gitattributes文件:

config.xml merge=ours

现在我签出并点HEAD到master,然后在测试中合并。因为master是我们的,test的.gitattributes没有签出,它会有影响吗?如果真的有效果,既然师父现在是“我们的”了,那又会怎样呢?


当前回答

澄清一下,如上所述,重基的意思是相反的,所以如果你看到

<<<<<<< HEAD
        foo = 12;
=======
        foo = 22;
>>>>>>> [your commit message]

使用'mine' -> foo = 12解决

解决使用'their ' -> foo = 22

其他回答

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

场景1。普通开发人员:你是不能合并到精通的开发人员,只能使用功能分支。

案例1:主人是国王。你想要刷新你的特性分支(= rebase to master),因为master包含了新的依赖项更新,而你想要覆盖你的小改动。

git checkout master
git pull

git checkout feature
git rebase -X ours master

情况2:你是国王。你想要重新建立你的特性分支来控制变化。但是您比您的同事做得更多,并且希望优先使用您自己的更改。

git checkout master
git pull

git checkout feature
git rebase -X theirs master

重要提示:正如你所看到的,普通的开发人员应该更喜欢重新创建数据库,并像每天早上锻炼/喝咖啡一样重复它。

场景2。合并老师:你是一个团队领导,想合并其他分支,并将合并的结果直接推给一个主。Master是一个分支,你会改变。

案例1:master is a king您想要合并第三方分支,但master是优先级。Feature是你前辈做的一个分支。

git checkout feature
git pull

git checkout master
git merge -X ours feature

当你的高级开发人员发布了一个很酷的功能,你想要覆盖主分支中的旧的东西。

git checkout feature
git pull

git checkout master
git merge -X theirs feature

记住:在午夜记得该选择哪一个:主人永远是我们的。这是他们的特色。

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

以下是基本原则:

合并:

$ git checkout master 
$ git merge feature

如果你想在master中选择版本:

$ git checkout --ours codefile.js

如果您想在功能中选择版本:

$ git checkout --theirs codefile.js

重置:

$ git checkout feature 
$ git rebase master 

如果你想在master中选择版本:

$ git checkout --ours codefile.js

如果您想在功能中选择版本:

$ git checkout --theirs codefile.js

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

我怀疑你在这里感到困惑,因为它从根本上令人困惑。更糟糕的是,当你在做rebase时,我们/他们的所有东西都转换了角色(变成了倒退)。

最终,在git合并过程中,“ours”分支指的是你要合并到的分支:

git checkout merge-into-ours

“their”分支指的是你要合并的(单个)分支:

git merge from-theirs

在这里,“ours”和“their”是有意义的,因为即使“their”可能是你的,“their”也不是你在运行git merge时使用的那个。

虽然使用实际的分支名称可能很酷,但在更复杂的情况下就不行了。例如,你可以这样做:

git checkout ours
git merge 1234567

通过原始commit-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是您要合并的版本。


“我们的”和“他们的”概念在改基过程中交换的原因是改基工作是通过做一系列的筛选,进入一个匿名分支(分离的HEAD模式)。目标分支是匿名分支,而merge-from分支是你的原始(预重基)分支:所以“——our”意味着匿名的一个重基正在构建,而“——their”意味着“我们的分支正在重基”。


至于gitattributes条目:它可能会产生影响:“ours”实际上在内部意味着“使用阶段#2”。但正如你所指出的,当时它还没有到位,所以它应该不会在这里产生影响……除非在开始之前将它复制到工作树中。

另外,顺便说一下,这适用于我们和他们的所有使用,但有些是在整个文件级别(-s我们的合并策略;git签出——在合并冲突时是我们的),有些是逐块的(在-s递归合并时是-X我们的或-X他们的)。这可能无助于解决任何困惑。

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

从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

在解决合并冲突时,你可以执行git checkout—他们的some_file和git checkout—我们的some_file来分别将文件重置为当前版本和传入版本。

如果你已经完成了git checkout——我们的some_file或git checkout——他们的some_file,并想要将文件重置为文件的3向合并版本,你可以执行git checkout——merge some_file。

澄清一下,如上所述,重基的意思是相反的,所以如果你看到

<<<<<<< HEAD
        foo = 12;
=======
        foo = 22;
>>>>>>> [your commit message]

使用'mine' -> foo = 12解决

解决使用'their ' -> foo = 22