在拉动期间解决Git合并冲突以支持其更改

Resolve Git merge conflicts in favor of their changes during a pull

如何解决Git合并冲突以支持拉式更改?

基本上,我需要从工作树中删除所有冲突的更改,而不必在保持所有无冲突更改的同时,经历与git mergetool的所有冲突。最好是边拉边做,而不是事后。


1
git pull -s recursive -X theirs <remoterepo or other repo>

或者,简单地说,对于默认存储库:

1
git pull -X theirs

如果你已经处于冲突状态…

1
git checkout --theirs path/to/file


您可以使用递归的"他们的"策略选项:

git merge --strategy-option theirs

从那个人:

1
2
3
4
5
6
7
8
9
10
11
12
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.

    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 opposite of ours.

注意:正如手册页所说,"我们的"合并策略选项与"我们的"合并策略非常不同。


如果你已经处于冲突状态,你只想接受他们所有的:

1
2
git checkout --theirs .
git add .

如果你想做相反的事情:

1
2
git checkout --ours .
git add .

这是非常激烈的,所以在做之前一定要像这样把所有的东西都清除掉。


好吧,想象一下我刚才的情景:

你尝试使用mergecherry-pick时,你被阻止了。

1
2
3
4
5
$ git cherry-pick 1023e24
error: could not apply 1023e24... [Commit Message]
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

现在,您查看有冲突的文件,您真的不想保留您的更改。在我上面的例子中,文件在我的IDE自动添加的新行上发生冲突。要撤消更改并接受更改,最简单的方法是:

1
2
git checkout --theirs path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php

相反(用您的版本覆盖传入的版本)是

1
2
git checkout --ours path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php

令人惊讶的是,我在网上很难找到这个答案。


git pull -X theirs的回答可能会造成一个丑陋的合并承诺,或发出一个

error: Your local changes to the following files would be overwritten by merge:

如果您只想忽略对repo文件的任何本地修改,例如在应该始终是源站镜像的客户机上,请运行该命令(用您想要的分支替换master):

1
git fetch && git reset --hard origin/master

它是如何工作的?git fetchgit pull但不合并。然后,git reset --hard使您的工作树与最后一次提交相匹配。您对repo中文件的所有本地更改都将被丢弃,但新的本地文件将被单独保留。


要解决与特定分支中的版本的所有冲突,请执行以下操作:

1
git diff --name-only --diff-filter=U | xargs git checkout ${branchName}

因此,如果您已经处于合并状态,并且希望保留冲突文件的主版本:

1
git diff --name-only --diff-filter=U | xargs git checkout master


请不要说这有时不起作用:

git checkout --ours path/to/file

git checkout --theirs path/to/file

我做了这个,假设头是我们的,合并头是他们的。

1
git checkout HEAD -- path/to/file

或:

1
git checkout MERGE_HEAD -- path/to/file

在我们这样做之后,我们很好:

1
git add .

如果您想了解更多信息,请查看Torek的精彩帖子:git checkout--我们的不会从未合并文件列表中删除文件


vs代码(集成Git)IDE用户:

如果要接受冲突文件中的所有传入更改,请执行以下步骤。

1
2
1. Go to command palette - Ctrl + Shift + P
2. Select the option - Merge Conflict: Accept All Incoming

同样,您也可以对其他选项执行此操作,例如"全部接受","全部接受当前值"等。


from https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging

This will basically do a fake merge. It will record a new merge commit
with both branches as parents, but it will not even look at the branch
you’re merging in. It will simply record as the result of the merge
the exact code in your current branch.

1
$ git merge -s ours mundo

Merge made by the 'ours' strategy.

1
$ git diff HEAD HEAD~

You can see that there is no difference between the branch we were on
and the result of the merge.

This can often be useful to basically trick Git into thinking that a
branch is already merged when doing a merge later on. For example, say
you branched off a release branch and have done some work on it that
you will want to merge back into your master branch at some point. In
the meantime some bugfix on master needs to be backported into your
release branch. You can merge the bugfix branch into the release
branch and also merge -s ours the same branch into your master branch
(even though the fix is already there) so when you later merge the
release branch again, there are no conflicts from the bugfix.

如果我想让master反映新主题分支的变化,我发现这种情况很有用。我注意到了-xtheirs在某些情况下不会在没有冲突的情况下合并…例如

1
2
3
$ git merge -Xtheirs topicFoo

CONFLICT (modify/delete): js/search.js deleted in HEAD and modified in topicFoo. Version topicFoo of js/search.js left in tree.

在这种情况下,我找到的解决方案是

1
$ git checkout topicFoo

从topicfoo开始,首先使用-s ours策略合并master,这将创建假提交,这只是topicfoo的状态。$git合并-s我们的主服务器

检查创建的合并提交

1
$ git log

现在检查主分支

1
$ git checkout master

将主题分支合并回去,但这次使用-xthers递归策略,这将向您展示一个具有topicfoo状态的主分支。

1
$ git merge -X theirs topicFoo