1687

如何解决 git 合并冲突以支持拉取更改?

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

4

12 回答 12

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

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

git pull -X theirs

如果您已经处于冲突状态...

git checkout --theirs path/to/file
于 2014-02-14T11:06:57.187 回答
1196

您可以使用递归“他们的”策略选项

git merge --strategy-option theirs

来自男人

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.

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

于 2012-05-22T07:24:00.177 回答
665

如果您已经处于冲突状态,并且您只想接受他们的所有内容:

git checkout --theirs .
git add .

如果你想做相反的事情:

git checkout --ours .
git add .

这是非常激烈的,所以在做之前确保你真的想像这样清除所有东西。

于 2015-11-06T15:18:44.943 回答
239

好的,想象一下我刚才所处的场景:

你尝试 a merge,或者也许 a cherry-pick,但你被阻止了

$ 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 自动添加的换行符上发生冲突。要撤消您的更改并接受他们的更改,最简单的方法是:

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

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

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

令人惊讶的是,我无法在网上很容易地找到这个答案。

于 2014-08-01T12:11:25.630 回答
51

答案可能会创建一个丑陋的git pull -X theirs合并提交,或者发出一个

错误:您对以下文件的本地更改将被合并覆盖:

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

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

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

于 2018-01-23T11:00:32.130 回答
26

如果您已经处于冲突状态,并且不想一一签出路径。你可以试试

git merge --abort
git pull -X theirs
于 2020-05-30T02:54:03.820 回答
22

要解决与特定分支中的版本的所有冲突:

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

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

git diff --name-only --diff-filter=U | xargs git checkout master
于 2015-07-14T17:43:32.530 回答
22

请注意,有时这不起作用

git checkout --我们的路径/到/文件

或者

git checkout --他们的路径/到/文件

我这样做了,假设HEAD 是我们的,而MERGE_HEAD 是他们的

git checkout HEAD -- path/to/file

或者:

git checkout MERGE_HEAD -- path/to/file

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

git add .

如果您想了解更多,请在此处查看 torek 的精彩帖子: git checkout --ours does not remove files from unmerged files list

于 2017-04-27T08:47:26.197 回答
22

VS Code(集成 Git)IDE 用户:

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

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

同样,您可以对其他选项进行操作,例如Accept All Both、Accept All Current 等,

于 2018-11-01T16:17:51.170 回答
8

git checkout --ours/theirs不完全解决冲突。它从任一ours/theirs.

假设我们有一个文件foo,其中包含两个提交/分支/树/任何内容的更改。如果他们引入了冲突以及修改,并且我们想使用ours-- 解决冲突,那么 usingcheckout --ours foo将丢弃引入冲突的更改,以及修改。

使用 SED

使用他们的解决方案:

sed -i -e '/^<<<<<<</,/^=======/d' -e '/^>>>>>>>/d' foo

  • -i就地修改文件,
  • /^<<<<<<</,/^=======/d删除<<<<<<<=======(我们的)之间的所有内容
  • /^>>>>>>>/d删除剩余的冲突标记
  • -e为 SED 指定多个模式
  • foo文件

使用我们的解决方案:

sed -i -e '/^<<<<<<</d' -e '/^=======/,/^>>>>>>>/d' foo

我制作了一个可以调用的脚本git resolve -o/-t/-b

创建自定义合并工具

您可以创建自定义合并工具。在上述sed脚本的基础上,您可以在您的git-config:

[mergetool "ours"]
    cmd = "sed -i -e '/^<<<<<<</d' -e '/^=======/,/^>>>>>>>/d' -- $MERGED"

并称之为git mergetool --tool=ours

于 2021-07-23T10:58:00.270 回答
3

我有一个长期运行的next-version分支,其中删除了大量已更改的develop文件,已在两个分支的不同位置添加的文件等。

我想将next-version分支的全部内容放入develop一个巨大的合并提交中。

对我有用的上述命令的组合是:

git merge -X theirs next-version
# lots of files left that were modified on develop but deleted on next-version
git checkout next-version .
# files removed, now add the deletions to the commit
git add .
# still have files that were added on develop; in my case they are all in web/
git rm -r web

这不是一个新的答案,只是结合了许多答案中的一些部分,部分是为了确保您可能需要所有这些答案。

于 2019-12-28T17:19:52.080 回答
1

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

这基本上会做一个假合并。它将以两个分支作为父分支记录一个新的合并提交,但它甚至不会查看您正在合并的分支。它只会将合并的结果记录为当前分支中的确切代码。

$ git merge -s ours mundo

由“我们的”战略进行的合并。

$ git diff HEAD HEAD~

可以看到我们所在的分支和合并的结果没有区别。

这通常很有用,可以基本上诱使 Git 在稍后进行合并时认为分支已经合并。例如,假设您从一个发布分支分支出来,并且已经完成了一些工作,您希望在某个时候合并回您的主分支。同时,需要将 master 上的一些错误修复移植到您的发布分支中。您可以将错误修复分支合并到发布分支中,也可以将相同的分支合并到您的主分支中(即使修复已经存在),因此当您稍后再次合并发布分支时,错误修复不会发生冲突。

如果我希望 master 反映新主题分支的更改,我发现这种情况很有用。我注意到 -Xtheirs 在某些情况下不会在没有冲突的情况下合并......例如

$ 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.

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

$ git checkout topicFoo

来自 topicFoo,首先使用 -s ours 策略合并到 master 中,这将创建只是 topicFoo 状态的假提交。$ git merge -s 我们的主人

检查创建的合并提交

$ git log

现在签出主分支

$ git checkout master

合并主题分支,但这次使用 -Xtheirs 递归策略,这将为您呈现一个主分支,其状态为 topicFoo。

$ git merge -X theirs topicFoo
于 2017-10-05T17:29:38.850 回答