【问题标题】:How do I resolve merge conflicts in a Git repository?如何解决 Git 存储库中的合并冲突?
【发布时间】:2010-09-14 18:40:54
【问题描述】:

我想解决我的 Git 存储库中的合并冲突。

我该怎么做?

【问题讨论】:

标签: git git-merge merge-conflict-resolution git-merge-conflict


【解决方案1】:
  1. 确定哪些文件存在冲突(Git 应该告诉你这一点)。

  2. 打开每个文件并检查差异; Git 对它们进行了划分。希望保留每个块的哪个版本是显而易见的。您可能需要与提交代码的其他开发人员讨论。

  3. 在文件git add the_file 中解决冲突后。

  4. 解决所有冲突后,执行git rebase --continue 或任何命令 完成后 Git 说要做。

【讨论】:

  • @Justin 将 Git 视为跟踪 内容 而不是跟踪文件。然后很容易看出你更新的内容不在仓库中,需要添加。这种思维方式也解释了为什么 Git 不跟踪空文件夹:虽然它们在技术上是文件,但没有任何内容可跟踪。
  • 内容存在,因为有 2 个版本的内容而发生冲突。因此“git add”听起来不正确。如果您只想在解决冲突后提交一个文件(“致命:在合并期间无法进行部分提交。”),它不起作用(git add,git commit)
  • 是的,从技术上讲,这回答了所问的问题,但在我看来,这不是一个可用的答案,抱歉。使一个分支与另一个分支相同的是什么?当然合并会有冲突..
  • Thulfir:谁说过要让一个分支和另一个分支一样?有不同的场景需要合并,而不是“使一个分支与另一个分支相同”。一种是当您完成开发分支并希望将其更改合并到主分支中时;在此之后,可以删除开发分支。另一个是当你想要重新定位你的开发分支时,以简化最终合并到 master 中的过程。
  • @JustinGrant git add 暂存索引中的文件;它确实向存储库添加任何内容。 git commit 将内容添加到存储库。这种用法对合并有意义——合并会自动暂存所有可以自动合并的更改;完成后,您有责任合并其余更改并将其添加到索引中。
【解决方案2】:

如果您经常进行小型提交,请先查看带有git log --merge 的提交 cmets。然后git diff 会告诉你冲突。

对于涉及多于几行的冲突,可以更轻松地查看外部 GUI 工具中发生的情况。我喜欢 opendiff——Git 还支持 vimdiff、gvimdiff、kdiff3、tkdiff、meld、xxdiff、emerge 开箱即用,您可以安装其他工具:git config merge.tool "your.tool" 将设置您选择的工具,然后在合并失败后显示 git mergetool你在上下文中的差异。

每次您编辑文件以解决冲突时,git add filename 都会更新索引,您的差异将不再显示。当所有的冲突都得到处理并且他们的文件已经git add-ed,git commit 将完成你的合并。

【讨论】:

  • 使用“git add”是真正的诀窍。您甚至可能不想提交(也许您想隐藏),但您必须执行“git add”才能完成合并。我认为 mergetool 会为您添加(虽然它不在手册页中),但如果您手动进行合并,则需要使用“git add”来完成它(即使您不想提交)。
【解决方案3】:

试试:git mergetool

它会打开一个 GUI,引导您完成每个冲突,然后您可以选择如何合并。有时它需要在之后进行一些手工编辑,但通常它本身就足够了。这当然比手工完成要好得多。

根据Josh Glover's comment

命令

除非您安装 GUI,否则不一定会打开 GUI。为我运行git mergetool 导致使用vimdiff。你可以安装 以下工具之一来使用它:meldopendiffkdiff3, tkdiff, xxdiff, tortoisemerge, gvimdiff, diffuse, ecmergep4mergearaxisvimdiffemerge

以下是使用vimdiff 解决合并冲突的示例过程。基于this link

第 1 步:在终端中运行以下命令

git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

这会将 vimdiff 设置为默认的合并工具。

第 2 步:在终端中运行以下命令

git mergetool

第 3 步:您将看到以下格式的 vimdiff 显示

  ╔═══════╦══════╦════════╗
  ║       ║      ║        ║
  ║ LOCAL ║ BASE ║ REMOTE ║
  ║       ║      ║        ║
  ╠═══════╩══════╩════════╣
  ║                       ║
  ║        MERGED         ║
  ║                       ║
  ╚═══════════════════════╝

这4个视图是

LOCAL - 这是来自当前分支的文件

BASE - 共同祖先,文件在两次更改之前的外观

REMOTE – 正在合并到分支的文件

MERGED - 合并结果,这是保存在 repo 中的内容

您可以使用 ctrl+w 在这些视图之间导航。您可以使用 ctrl+w 后跟 j 直接到达 MERGED 视图。

有关 vimdiff 导航的更多信息是 herehere

第 4 步。您可以通过以下方式编辑 MERGED 视图

如果您想从 REMOTE 获取更改

:diffg RE

如果你想从 BASE 获取更改

:diffg BA

如果您想从 LOCAL 获取更改

:diffg LO

第 5 步。保存、退出、提交和清理

:wqa保存并退出vi

git commit -m "message"

git clean 删除 diff 工具创建的额外文件(例如 *.orig)。

【讨论】:

  • 仅供参考,如果您要一次合并大量文件,您可以使用 git mergetool -y 来节省一些按键操作。
  • 嗯,它不一定会打开一个 GUI,除非你安装一个。为我运行git mergetool 导致vimdiff 被使用。您可以安装以下工具之一来使用它:meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge
  • 好点乔希。在 ubuntu 上,我的 meld 运气最好,它的三向合并显示还不错。在 OSX 上,git 选择了一个不错的默认值。
  • 这打开了 KDiff3。我完全不知道如何使用。
  • 您现在也可以使用 Beyond Compare 3 (git mergetool -t bc3)。
【解决方案4】:

查看 Stack Overflow 问题 Aborting a merge in Git 中的答案,尤其是 Charles Bailey's answer,它显示了如何查看有问题的文件的不同版本,例如,

# Common base version of the file.
git show :1:some_file.cpp

# 'Ours' version of the file.
git show :2:some_file.cpp

# 'Theirs' version of the file.
git show :3:some_file.cpp

【讨论】:

  • 还可以查看“git checkout -m”的“-m”选项 - 它允许您将不同的苍蝇提取回您的工作区
  • 这救了我。分别查看每个文件让我记住了我在每个分支中的目标。然后我可以做出选择的决定。
【解决方案5】:

这是一个可能的用例,从顶部开始:

您将进行一些更改,但是糟糕,您不是最新的:

git fetch origin
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

所以你更新并重试,但有冲突:

git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.

所以你决定看看这些变化:

git mergetool

哦,我的,哦,我的,上游更改了一些东西,但只是为了使用我的更改...不...他们的更改...

git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"

然后我们尝试最后一次

git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

哒哒!

【讨论】:

  • 这非常有用,因为我有很多与二进制文件(艺术资产)的合并错误并且合并这些似乎总是失败,所以我需要用新文件覆盖它而不是“合并"
  • 小心! --ours 和 --theirs 的含义相反。 --ours == 遥控器。 --他们的==本地的。见git merge --help
  • 就我而言,我确认 --theirs = 远程存储库,--ours = 我自己的本地存储库。它与@mmell cmets 相反。
  • @mmell 显然只在变基上。见this question
  • 伙计们,“我们的”和“他们的”与您是合并还是变基有关。如果您要合并,那么“我们的”表示您要合并的分支,“他们的”是您要合并的分支。当您 rebase 时,“我们的”表示您要重新调整的提交, 而 "theirs" 指的是你想要变基的提交。
【解决方案6】:

我发现合并工具很少能帮助我理解冲突或解决方案。在文本编辑器中查看冲突标记并使用 git log 作为补充时,我通常会更成功。

这里有一些提示:

提示一

我发现最好的方法是使用“diff3”合并冲突样式:

git config merge.conflictstyle diff3

这会产生这样的冲突标记:

<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a 
feature/topic branch.
>>>>>>>

中间部分是共同祖先的样子。这很有用,因为您可以将其与顶部和底部版本进行比较,以更好地了解每个分支上的更改内容,从而更好地了解每个更改的目的。

如果冲突只有几行,这通常会使冲突非常明显。 (知道如何解决冲突是非常不同的;你需要知道其他人在做什么。如果你感到困惑,最好把那个人叫到你的房间,这样他们就可以看到你在看什么在。)

如果冲突时间较长,那么我将三个部分分别剪切并粘贴到三个单独的文件中,例如“我的”、“普通的”和“他们的”。

然后我可以运行以下命令来查看导致冲突的两个 diff hunk:

diff common mine
diff common theirs

这与使用合并工具不同,因为合并工具也会包含所有不冲突的差异数据块。我觉得这很让人分心。

提示二

有人已经提到了这一点,但是了解每个差异大块背后的意图通常对于了解冲突的来源以及如何处理它非常有帮助。

git log --merge -p <name of file>

这显示了在共同祖先和您要合并的两个头之间触及该文件的所有提交。 (因此它不包括合并之前两个分支中已经存在的提交。)这有助于您忽略明显不是当前冲突因素的差异大块。

提示三

使用自动化工具验证您的更改。

如果您有自动化测试,请运行它们。如果您有lint,请运行它。如果它是一个可构建的项目,那么在提交之前构建它,等等。在所有情况下,您都需要进行一些测试以确保您的更改不会破坏任何东西。 (哎呀,即使没有冲突的合并也会破坏工作代码。)

提示四

提前计划;与同事交流。

提前计划并了解其他人正在处理的工作有助于防止合并冲突和/或帮助更早地解决这些冲突——而细节仍然是新鲜的。

例如,如果您知道您和另一个人都在进行不同的重构,这些重构都会影响同一组文件,那么您应该提前相互交谈,并更好地了解各自的更改类型你们正在制作。如果您按顺序而不是并行进行计划更改,您可能会节省大量时间和精力。

对于涉及大量代码的重大重构,您应该强烈考虑按顺序工作:每个人都停止在代码的该区域工作,而一个人执行完整的重构。

如果您不能连续工作(可能是由于时间压力),那么就预期的合并冲突进行沟通至少可以帮助您在细节仍然清晰的同时更快地解决问题。例如,如果一个同事在一周内进行了一系列破坏性的提交,您可以选择在该周内每天一次或两次在该同事分支上合并/rebase。这样一来,如果您确实发现了合并/变基冲突,您可以更快地解决它们,而不是等待几周将所有内容合并到一个大块中。

提示五

如果您不确定合并,请不要强行合并。

合并可能会让人感到不知所措,尤其是当存在大量冲突文件且冲突标记覆盖数百行时。通常,在估算软件项目时,我们没有足够的时间来处理诸如处理复杂合并之类的开销项目,因此花几个小时剖析每个冲突感觉真的很累。

从长远来看,提前计划并了解其他人正在做什么是预测合并冲突并准备好在更短的时间内正确解决它们的最佳工具。

【讨论】:

  • diff3 选项是一个很棒的合并功能。我遇到的唯一显示它的 GUI 是 Perforce 的 p4merge,它可以与 Perforce 的其他工具分开安装和使用(我没有使用过,但听说过抱怨)。
  • 在 rebase 尝试导致合并冲突后:$ git log --merge -p build.xml 输出:致命:--merge without MERGE_HEAD?
  • git config merge.conflictstyle diff3 - 谢谢你,先生。这是惊人的,并让我从试图找到(并支付 $$)一个好的 3 路合并 GUI 中解脱出来。 IMO这更好,因为它显示了共同的祖先以及本地/远程,显示了(AFAIK)没有GUI的最后提交日志行。提交绝对可以帮助您确定哪些代码属于哪个分支。
  • 我发现有时 diff3 冲突风格会导致巨大的差异数据块在很大程度上是相同的,而默认值会产生更小、更易于管理的数据块。不幸的是,我没有可用于错误报告的复制器。但是如果你遇到这个问题,你可能会考虑暂时关闭该选项。
  • 大 +1 推荐 diff3。默认的冲突风格使得一些冲突实际上无法解决。欲了解更多信息,请参阅stackoverflow.com/questions/27417656/…
【解决方案7】:

对于想要半手动解决合并冲突的Emacs 用户:

git diff --name-status --diff-filter=U

显示所有需要解决冲突的文件。

一个一个地打开这些文件,或者一次打开所有文件:

emacs $(git diff --name-only --diff-filter=U)

在 Emacs 中访问需要编辑的缓冲区时,键入

ALT+x vc-resolve-conflicts

这将打开三个缓冲区(我的、他们的和输出缓冲区)。按“n”(下一个区域)、“p”(预置区域)进行导航。按“a”和“b”分别将我的或他们的区域复制到输出缓冲区。和/或直接编辑输出缓冲区。

完成后:按“q”。 Emacs 询问您是否要保存此缓冲区:是的。 完成缓冲区后,通过从终端运行将其标记为已解决:

git add FILENAME

当完成所有缓冲区类型时

git commit

完成合并。

【讨论】:

    【解决方案8】:

    您可以通过其他方法详细说明的多种方式修复合并冲突。

    我认为真正的关键是了解本地和远程存储库的变化是如何流动的。关键是理解跟踪分支。我发现我认为跟踪分支是我的本地实际文件目录和定义为源的远程目录之间的“中间缺失的部分”。

    我个人养成了两件事来帮助避免这种情况的习惯。

    代替:

    git add .
    git commit -m"some msg"
    

    这有两个缺点 -

    a) 添加所有新的/更改的文件,其中可能包括一些不需要的更改。
    b) 您不能先查看文件列表。

    所以我这样做了:

    git add file,file2,file3...
    git commit # Then type the files in the editor and save-quit.
    

    这样,您可以更仔细地考虑添加哪些文件,并且您还可以查看列表并在使用消息编辑器时进行更多思考。我发现当我使用全屏编辑器而不是 -m 选项时,它还改进了我的提交消息。

    [更新 - 随着时间的流逝,我已经切换到更多:

    git status # Make sure I know whats going on
    git add .
    git commit # Then use the editor
    

    ]

    另外(并且与您的情况更相关),我尽量避免:

    git pull
    

    git pull origin master.
    

    因为 pull 意味着合并,如果您在本地有不想合并的更改,您很容易以合并代码和/或不应该合并的代码的合并冲突告终。

    相反,我尝试去做

    git checkout master
    git fetch   
    git rebase --hard origin/master # or whatever branch I want.
    

    您也可能会发现这很有帮助:

    git branch, fork, fetch, merge, rebase and clone, what are the differences?

    【讨论】:

    • 嘿,我有点明白你的回答了。但是由于我是 github 合并冲突的新手,所以我认为缺少一些东西。当您执行 git checkout mastergit fetchgit rebase --hard origin/master 时,您的本地修改会发生什么情况
    • 我相信你应该添加更多关于做什么的细节。另一个让我困惑的例子,你在回答中提到:我们做git add .,它会保存我们的本地修改以便我们可以跟进git checkout master吗?还是它们是两种不同的场景?
    • @MichaelDurrant $ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option hard' 用法:git rebase [-i] [options] [--exec ] [--onto ] [] [] 或:git rebase [-i] [options] [--exec ] [--onto ] --root [] 或:git rebase --continue | --中止 | --跳过 | --edit-todo `
    【解决方案9】:

    请参阅 How Conflicts Are Presented 或 Git 中的 git merge 文档以了解什么是合并冲突标记。

    另外,How to Resolve Conflicts 部分解释了如何解决冲突:

    看到冲突后,你可以做两件事:

    • 决定不合并。您需要的唯一清理是将索引文件重置为HEAD 提交以反转 2. 并清理 2. 和 3. 所做的工作树更改; git merge --abort 可以用于此。

    • 解决冲突。 Git 将标记工作树中的冲突。将文件编辑成 shape 并 git add 将它们添加到索引中。使用git commit 达成交易。

    您可以使用多种工具解决冲突:

    • 使用合并工具。 git mergetool 启动图形合并工具,它将帮助您完成合并。

    • 查看差异。 git diff 将显示三向差异,突出显示 HEADMERGE_HEAD 版本的变化。

    • 查看每个分支的差异。 git log --merge -p &lt;path&gt; 将首先显示 HEAD 版本的差异,然后是 MERGE_HEAD 版本。

    • 查看原件。 git show :1:filename 显示共同祖先,git show :2:filename 显示HEAD 版本,git show :3:filename 显示MERGE_HEAD 版本。

    您还可以在Pro Git 书籍部分Basic Merge Conflicts 中阅读有关合并冲突标记以及如何解决它们的信息。

    【讨论】:

      【解决方案10】:

      CoolAJ86 的回答几乎概括了一切。如果您在同一段代码中对两个分支进行了更改,则必须进行手动合并。在任何文本编辑器中打开冲突文件,您应该会看到以下结构。

      (Code not in Conflict)
      >>>>>>>>>>>
      (first alternative for conflict starts here)
      Multiple code lines here
      ===========
      (second alternative for conflict starts here)
      Multiple code lines here too    
      <<<<<<<<<<<
      (Code not in conflict here)
      

      以您希望新代码的方式选择其中一种或两种方式的组合,同时删除等号和尖括号。

      git commit -a -m "commit message"
      git push origin master
      

      【讨论】:

        【解决方案11】:

        如果不使用工具进行合并,请先将代码复制到外面:

        - `checkout master`
        - `git pull` / get new commit
        - `git checkout` to your branch
        - `git rebase master`
        

        它解决了冲突,你可以复制你的代码。

        【讨论】:

        • 这个顺序总是有帮助吗?请解释它的作用和方式以及该代码如何回答问题。
        【解决方案12】:

        如果要从分支test 合并到master,可以按照以下步骤操作:

        第一步:去分店

        git checkout test
        

        第 2 步

        git pull --rebase origin master
        

        第三步:如果有冲突,到这些文件去修改。

        第 4 步:添加这些更改

        git add #your_changes_files
        

        第 5 步

        git rebase --continue
        

        第 6 步:如果仍有冲突,请再次返回第 3 步。如果没有冲突,请执行以下操作:

        git push origin +test
        

        第七步:然后test和master之间就没有冲突了。可以直接使用merge。

        【讨论】:

          【解决方案13】:
          git log --merge -p [[--] path]
          

          似乎并不总是对我有用,并且通常最终会显示两个分支之间不同的每个提交,即使使用 -- 将路径与命令分开也会发生这种情况。

          解决此问题的方法是打开两个命令行并一次运行

          git log ..$MERGED_IN_BRANCH --pretty=full -p [path]
          

          在另一个

          git log $MERGED_IN_BRANCH.. --pretty=full -p [path]
          

          用我合并的分支替换$MERGED_IN_BRANCH,用冲突的文件替换[path]。此命令将以补丁形式记录 (..) 两次提交之间的所有提交。如果您像上面的命令一样将一侧留空,git 将自动使用HEAD(在这种情况下您要合并到的分支)。

          这将允许您查看两个分支在分歧后进入文件的提交。它通常使解决冲突变得容易得多。

          【讨论】:

            【解决方案14】:

            我总是按照以下步骤来避免冲突。

            • git checkout master(来到master分支)
            • git pull(更新你的master获取最新代码)
            • git checkout -b mybranch(签出一个新的分支并开始在该分支上工作,以便您的 master 始终保持在主干的顶部。)
            • git add . and git commit and git push(在您的本地分支上更改后)
            • git checkout master(回到你的主人那里)

            现在,您只需在必要时对您的分支发送git checkout,即可执行相同的操作并维护任意数量的本地分支并同时工作。

            【讨论】:

              【解决方案15】:

              请按照以下步骤修复 Git 中的合并冲突:

              1. 检查 Git 状态: git 状态

              2. 获取补丁集: git fetch(从您的 Git 提交中签出正确的补丁)

              3. 签出本地分支(此处为 temp1): git checkout -b temp1

              4. 从master拉取最近的内容: git pull --rebase origin master

              5. 启动合并工具并检查冲突并修复它们...并使用当前分支检查远程分支中的更改: git 合并工具

              6. 再次检查状态: git 状态

              7. 删除mergetool本地创建的不需要的文件,通常mergetool会创建带有*.orig扩展名的额外文件。请删除该文件,因为它只是重复的并在本地修复更改并添加正确版本的文件。 git add #your_changed_correct_files

              8. 再次检查状态: git 状态

              9. 将更改提交到相同的提交 ID(这避免了新的单独补丁集): git commit --amend

              10. 推送到主分支: git push(到您的 Git 存储库)

              【讨论】:

                【解决方案16】:

                同时对文件进行更改时会发生合并冲突。以下是解决方法。

                gitCLI

                以下是您进入冲突状态时的简单步骤:

                1. 注意冲突文件列表:git status(在Unmerged paths 部分下)。
                2. 通过以下方法之一分别解决每个文件的冲突:

                  • 使用 GUI 解决冲突:git mergetool(最简单的方法)。

                  • 要接受远程/其他版本,请使用:git checkout --theirs path/file。这将拒绝您对该文件所做的任何本地更改。

                  • 要接受本地/我们的版本,请使用:git checkout --ours path/file

                    但是你必须小心,因为远程更改是由于某种原因造成的冲突。

                    相关:What is the precise meaning of "ours" and "theirs" in git?

                  • 手动编辑冲突文件并查找&lt;&lt;&lt;&lt;&lt;/&gt;&gt;&gt;&gt;&gt; 之间的代码块,然后从===== 上方或下方选择版本。请参阅:How conflicts are presented

                  • 路径和文件名冲突可以通过git add/git rm解决。

                3. 最后,使用git status 查看准备提交的文件。

                  如果您在Unmerged paths 下仍有任何文件,并且您确实手动解决了冲突,那么请让 Git 知道您通过以下方式解决了它:git add path/file

                4. 如果所有冲突都已成功解决,请通过:git commit -a 提交更改并照常推送到远程。

                另请参阅:Resolving a merge conflict from the command line 在 GitHub

                实用教程请查看:Scenario 5 - Fixing Merge Conflicts by Katacoda

                差异合并

                我已经成功使用DiffMerge,它可以在 Windows、macOS 和 Linux/Unix 上直观地比较和合并文件。

                它可以以图形方式显示 3 个文件之间的更改,并允许自动合并(在安全的情况下)并完全控制编辑结果文件。

                图片来源:DiffMerge(Linux截图)

                只需下载它并在 repo 中运行:

                git mergetool -t diffmerge .
                

                macOS

                在 macOS 上,您可以通过以下方式安装:

                brew install caskroom/cask/brew-cask
                brew cask install diffmerge
                

                并且可能(如果未提供)您需要在 PATH 中放置以下额外简单的包装器(例如 /usr/bin):

                #!/bin/sh
                DIFFMERGE_PATH=/Applications/DiffMerge.app
                DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
                exec ${DIFFMERGE_EXE} --nosplash "$@"
                

                然后您可以使用以下键盘快捷键:

                • -Alt-Up/Down 跳转到上一个/下一个更改。
                • -Alt-Left/Right接受从左到右的变化

                您也可以使用opendiff(Xcode 工具的一部分),它可以让您将两个文件或目录合并在一起以创建第三个文件或目录。

                【讨论】:

                  【解决方案17】:

                  奖金:

                  说到前面的答案中的 pull/fetch/merge,我想分享一个有趣且富有成效的技巧,

                  git pull --rebase

                  上面的这个命令是我 Git 生活中最有用的命令,它节省了很多时间。

                  在将您新提交的更改推送到远程服务器之前,请尝试git pull --rebase 而不是git pull 和手动merge,它会自动同步最新的远程服务器更改(使用获取+合并)并将您的本地最新提交在 Git 日志的顶部。无需担心手动拉/合并。

                  如果发生冲突,只需使用

                  git mergetool
                  git add conflict_file
                  git rebase --continue
                  

                  详情请访问:What does “git pull –rebase” do?

                  【讨论】:

                    【解决方案18】:

                    简单地说,如果您很清楚其中一个存储库中的更改并不重要,并且想要解决所有更改以支持另一个存储库,请使用:

                    git checkout . --ours
                    

                    解决有利于您的存储库的更改,或

                    git checkout . --theirs
                    

                    解决有利于其他或主存储库的更改。

                    否则您将不得不使用 GUI 合并工具逐个浏览文件,例如合并工具是 p4merge,或者写下您已经安装的任何人的名字

                    git mergetool -t p4merge
                    

                    在完成一个文件后,您必须保存并关闭,以便打开下一个文件。

                    【讨论】:

                    • git 结帐。 --theirs 解决了我的问题,谢谢
                    • 如果您更喜欢手动解决冲突,请尝试在 Visual Studio Code 中打开该文件夹,它会在每个文件中标记带有冲突和颜色冲突行的文件
                    【解决方案19】:

                    合并冲突可能发生在不同的情况下:

                    • 当运行git fetch 然后git merge
                    • 当运行git fetch 然后git rebase
                    • 运行git pull时(实际上等于上述条件之一)
                    • 运行时git stash pop
                    • 当您应用 git 补丁时(导出到要传输的文件的提交,例如通过电子邮件)

                    您需要安装与 Git 兼容的合并工具来解决冲突。我个人使用KDiff3,我发现它很好用。你可以在这里下载它的 Windows 版本:

                    https://sourceforge.net/projects/kdiff3/files/

                    顺便说一句,如果你安装 Git Extensions,在它的安装向导中有一个选项可以安装 Kdiff3。

                    然后设置 Git 配置以使用 KDiff3 作为其合并工具:

                    $ git config --global --add merge.tool kdiff3
                    $ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
                    $ git config --global --add mergetool.kdiff3.trustExitCode false
                    
                    $ git config --global --add diff.guitool kdiff3
                    $ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
                    $ git config --global --add difftool.kdiff3.trustExitCode false
                    

                    (记得用KDiff3 EXE文件的实际路径替换路径。)

                    那么每次遇到合并冲突时,只需要运行这个命令即可:

                    $ git mergetool
                    

                    然后它打开 Kdiff3,并首先尝试自动解决合并冲突。大多数冲突会自发解决,其余的需要您手动解决。

                    这是 Kdiff3 的样子:

                    完成后,保存文件,它会转到下一个有冲突的文件,然后你再次执行相同的操作,直到所有冲突都解决。

                    要检查所有内容是否合并成功,只需再次运行 mergetool 命令。你应该得到这个结果:

                    $ git mergetool
                    No files need merging
                    

                    【讨论】:

                      【解决方案20】:

                      我想要我或他们的完整版本,或者想要查看个别更改并为每个更改做出决定。

                      完全接受我或他们的版本

                      接受我的版本(本地,我们的):

                      git checkout --ours -- <filename>
                      git add <filename>              # Marks conflict as resolved
                      git commit -m "merged bla bla"  # An "empty" commit
                      

                      接受他们的版本(远程,他们的):

                      git checkout --theirs -- <filename>
                      git add <filename>
                      git commit -m "merged bla bla"
                      

                      如果您想针对所有冲突文件运行:

                      git merge --strategy-option ours
                      

                      git merge --strategy-option theirs
                      

                      查看所有更改并逐一接受

                      1. git mergetool
                      2. 查看更改并为每个更改接受任一版本。
                      3. git add &lt;filename&gt;
                      4. git commit -m "merged bla bla"

                      默认mergetool命令行中工作。如何使用命令行合并工具应该是一个单独的问题。

                      您也可以为此安装可视化工具,例如meld 并运行

                      git mergetool -t meld
                      

                      它将打开本地版本(我们的)、“基础”或“合并”版本(合并的当前结果)和远程版本(他们的)。完成后保存合并后的版本,再次运行git mergetool -t meld,直到出现“没有文件需要合并”,然后转到步骤 3 和 4。

                      【讨论】:

                        【解决方案21】:

                        使用patience

                        对于大的合并冲突,使用patience 为我提供了很好的结果。它将尝试匹配块而不是单个行。

                        例如,如果您更改程序的缩进,默认的 Git 合并策略有时会匹配属于不同函数的单大括号 {patience 可以避免这种情况:

                        git merge -s recursive -X patience other-branch
                        

                        来自文档:

                        With this option, merge-recursive spends a little extra time to avoid 
                        mismerges that sometimes occur due to unimportant matching lines 
                        (e.g., braces from distinct functions). Use this when the branches to 
                        be merged have diverged wildly.
                        

                        与共同祖先的比较

                        如果您有合并冲突并想看看其他人在修改他们的分支时的想法,有时将他们的分支直接与共同祖先(而不是我们的分支)进行比较更容易。为此,您可以使用merge-base:

                        git diff $(git merge-base <our-branch> <their-branch>) <their-branch>
                        

                        通常,您只想查看特定文件的更改:

                        git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
                        

                        【讨论】:

                        • 就我而言,这并不能很好地解决合并冲突,因为由于某种原因,它在 C# 项目中保留了重复的配置行。虽然它比我之前的 ENTIRE FILE IS DIFFERENT 更友好
                        【解决方案22】:

                        解决冲突的更安全的方法是使用git-mediate(这里建议的常见解决方案很容易出错)。

                        请参阅this post 以快速了解如何使用它。

                        【讨论】:

                          【解决方案23】:

                          截至 2016 年 12 月 12 日,您可以合并分支并解决 github.com 上的冲突

                          因此,如果您不想使用命令行或此处提供的旧答案中的任何第 3 方工具,请使用 GitHub 的本机工具。

                          This blog post 详细解释,但基本原理是通过 UI '合并'两个分支后,您现在将看到一个“解决冲突”选项,该选项将带您进入允许您处理这些合并冲突的编辑器.

                          【讨论】:

                          • 这不是在询问 github,因此我否决了我认为非常糟糕的答案。
                          • @mschuett 是对的,问题是“如何解决 git 中的冲突”,而不是“如何解决 github 中的冲突”。这是有区别的,已经有太多人认为 git 和 github 是同一个东西,所以任何传播这种感觉的东西都是错误的。
                          【解决方案24】:

                          根据 GitHub blog post“您现在可以直接从您的拉取请求解决 GitHub 上的简单合并冲突,从而节省您前往命令行的时间,并帮助您的团队更快地合并拉取请求。” em>

                          简单来说,你可以在 GitHub 上push your changes to your remote repositorymerge your changes in a pull request

                          请使用以下官方GitHub link,简单步骤说明流程。

                          如果你不想使用 GitHub,那么你可以随时使用 difftool。我推荐的是Meld。请看视频教程here

                          【讨论】:

                            【解决方案25】:

                            分为三个步骤:

                            1. 通过命令查找导致冲突的文件

                               git status
                              
                            2. 检查文件,您会在其中找到标记为类似的冲突

                               <<<<<<<<head
                               blablabla
                              
                            3. 将其更改为您想要的方式,然后使用命令提交

                               git add solved_conflicts_files
                               git commit -m 'merge msg'
                              

                            【讨论】:

                            • 为我工作!谢谢!
                            • rebase 的时候一定要注意。你应该使用 git rebase --continue 而不是 git commit
                            【解决方案26】:
                            git fetch <br>
                            git checkout **your branch**<br>
                            git rebase master<br>
                            

                            在此步骤中,您将尝试使用首选 IDE 解决冲突。

                            您可以关注this link查看如何修复文件中的冲突。

                            git add<br>
                            git rebase --continue<br>
                            git commit --amend<br>
                            git push origin HEAD:refs/drafts/master  (push like a drafts)<br>
                            

                            现在一切正常,您将在 Gerrit 中找到您的提交。

                            【讨论】:

                              【解决方案27】:

                              对于那些使用 Visual Studio 的人(在我的例子中是Visual Studio 2015

                              1. 在 Visual Studio 中关闭您的项目。尤其是在大型项目中,Visual Studio 在使用 UI 进行合并时往往会崩溃。

                              2. 在命令提示符下进行合并。

                                git checkout target_branch

                                git 合并源分支

                              3. 然后在 Visual Studio 中打开项目并转到 Team Explorer → Branch。现在有一条消息显示 Merge is pending,并且在消息下方列出了冲突文件。

                              4. 单击冲突文件,您将可以选择合并比较获取源获取目标时间>。 Visual Studio 中的合并工具非常好用。

                              【讨论】:

                              • 我在一个非常大的项目上使用 VS Code 2017,不需要关闭该项目。它处理得很好:)
                              【解决方案28】:

                              如果您使用 IntelliJ IDEA 作为 IDE,请尝试通过以下方式将父级合并到您的分支:

                              git checkout <localbranch>
                              git merge origin/<remotebranch>
                              

                              它将像这样显示所有冲突:

                              A_MBPro:test anu$ git merge origin/ 自动合并 src/test/java/com/.../TestClass.java 冲突 (内容):合并冲突 src/test/java/com/.../TestClass.java

                              现在请注意,TestClass.java 文件在 IntelliJ IDEA 中显示为红色。

                              git status 也会显示:

                              Unmerged paths:
                              (use "git add <file>..." to mark resolution)
                              both modified:   src/test/java/com/.../TestClass.java
                              

                              在 IntelliJ IDEA 中打开文件。它将包含带有

                              的部分
                                <<<<<<< HEAD
                                  public void testMethod() {
                                  }
                                  =======
                                  public void testMethod() { ...
                                  }
                                  >>>>>>> origin/<remotebranch>
                              

                              HEAD 是本地分支的更改,而 origin/ 是远程分支的更改。在这里保留您需要的东西并删除您不需要的东西。之后,应该执行正常步骤。那是

                                 git add TestClass.java
                                 git commit -m "commit message"
                                 git push
                              

                              【讨论】:

                                【解决方案29】:

                                用途:

                                git checkout branch1
                                git fetch origin
                                git rebase -p origin/mainbranch
                                

                                如果存在合并冲突,请修复它们。然后,通过运行继续 rebase 过程:git rebase –-continue

                                修复后,您可以提交本地分支并将其推送到远程分支:

                                git push origin branch1
                                

                                【讨论】:

                                  【解决方案30】:

                                  我遵循以下流程。

                                  修复合并冲突的过程:

                                  1. 首先,从要合并到的目标分支中提取最新的git pull origin develop

                                  2. 当您从目的地获得最新信息时,现在通过删除那些多余的字符在 IDE 中手动解决冲突。

                                  3. 执行git add 将这些已编辑的文件添加到 Git 队列中,以便它可以是 commitpush 到您正在处理的同一分支。

                                  4. git add 完成后,执行 git commit 以提交更改。

                                  5. 现在通过git push origin HEAD将更改推送到您的工作分支

                                  就是这样,如果您使用的是 Bitbucket 或 GitHub,您将在拉取请求中看到它已解决。

                                  【讨论】:

                                    猜你喜欢
                                    • 1970-01-01
                                    • 2015-10-15
                                    • 2018-08-04
                                    • 1970-01-01
                                    • 2018-04-19
                                    • 2017-05-10
                                    • 1970-01-01
                                    • 2012-04-07
                                    • 2016-11-08
                                    相关资源
                                    最近更新 更多