如何解决Git存储库中的合并冲突?

如何解决我的Git存储库中的合并冲突?

3315851 次浏览
  1. 确定哪些文件存在冲突(Git应该会告诉你这一点)。

  2. 打开每个文件并检查差异;Git划分它们。希望可以清楚地知道要保留每个块的哪个版本。您可能需要与提交代码的开发人员讨论。

  3. 一旦您解决了文件git add the_file中的冲突。

  4. 一旦你解决了所有冲突,执行git rebase --continue或其他命令Git说完成后再做。

如果您经常进行小提交,那么首先查看带有git log --merge的提交注释。然后git diff将向您显示冲突。

对于不止几行的冲突,在外部GUI工具中更容易看到发生了什么。我喜欢opendiff——Git还支持vimdiff、gvimdiff、kdiff、tkdiff、meld、xxdiff,开箱即用,您可以安装其他:git config merge.tool "your.tool"将设置您选择的工具,然后失败合并后的git mergetool将向您显示上下文中的差异。

每次编辑文件以解决冲突时,git add filename都会更新索引,您的diff将不再显示它。当所有冲突都被处理并且它们的文件已被git add编辑时,git commit将完成您的合并。

尝试:

git mergetool

它打开一个GUI,引导您完成每个冲突,您可以选择如何合并。有时它需要一些手工编辑,但通常它本身就足够了。这肯定比手工完成整个事情要好得多。


根据乔什·格洛弗的评论

[此命令]不一定打开GUI,除非您安装一个。为我运行git mergetool导致使用vimdiff。您可以安装以下工具之一来代替它:meldopendiffkdiff3tkdiffxxdifftortoisemergegvimdiffdiffuseecmergep4mergearaxisvimdiffemerge.


下面是基于此链接使用vimdiff解决合并冲突的示例过程。

  1. 在终端中运行以下命令

    git config merge.tool vimdiffgit config merge.conflictstyle diff3git config mergetool.prompt false

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

  2. 在终端中运行以下命令

    git mergetool
  3. 您将看到以下格式的vimdiff显示:

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

    这4个观点是

    • 当地:这是当前分支的文件
    • 基地:共同祖先,在两次更改之前这个文件的外观
    • 远程:您正在合并到分支中的文件
    • 合并:合并结果;这是保存在合并提交中并在将来使用的内容

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

    关于vimdiff导航的更多信息是这里这里

  4. 您可以像这样编辑合并视图:

    • 如果您想从远程获取更改

      :diffg RE
    • 如果您想从BASE获取更改

      :diffg BA
    • 如果您想从本地获取更改

      :diffg LO
  5. 保存、退出、提交和清理

    :wqa保存并退出vi

    git commit -m "message"

    git clean删除额外的文件(例如*.orig)。警告:如果您不传递任何参数,它将删除所有未跟踪的文件。

查看Stack Overflow问题在Git中中止合并中的答案,尤其是查尔斯·贝利的回答,它展示了如何查看有问题的文件的不同版本,例如,

# 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 fetch origingit pull origin master
From ssh://gitosis@example.com:22/projectname* branch            master     -> FETCH_HEADUpdating a030c3a..ee25213error: Entry 'filename.c' not uptodate. Cannot merge.

所以你更新并再试一次,但有冲突:

git add filename.cgit commit -m "made some wild and crazy changes"git pull origin master
From ssh://gitosis@example.com:22/projectname* branch            master     -> FETCH_HEADAuto-merging filename.cCONFLICT (content): Merge conflict in filename.cAutomatic merge failed; fix conflicts and then commit the result.

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

git mergetool

哦,我的,哦,我的,上游改变了一些东西,但只是用我的改变……不……他们的改变……

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

然后我们尝试最后一次

git pull origin master
From ssh://gitosis@example.com:22/projectname* branch            master     -> FETCH_HEADAlready up-to-date.

Ta-da!

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

以下是一些提示:

提示一

我发现的最好的事情是使用“扩散3”合并冲突样式:

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 afeature/topic branch.>>>>>>>

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

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

如果冲突较长,那么我将把这三个部分中的每一个剪切并粘贴到三个单独的文件中,例如“我的”,“共同的”和“他们的”。

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

diff common minediff common theirs

这与使用合并工具不同,因为合并工具也将包含所有不冲突的diff块。我发现这会分散注意力。

提示二

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

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

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

提示三

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

如果你有自动化测试,运行那些。如果你有皮棉,运行那个。如果它是一个可构建的项目,那么在提交之前构建它,等等。在所有情况下,你需要做一些测试来确保你的更改不会破坏任何东西。(见鬼,即使是没有冲突的合并也会破坏工作代码。)

提示四

提前计划;与同事沟通。

提前计划并了解其他人正在做什么可以帮助防止合并冲突和/或帮助更早地解决它们-而细节仍然记忆犹新。

例如,如果你知道你和另一个人都在进行不同的重构,这都将影响同一组文件,你应该提前互相交谈,更好地了解你们每个人正在做什么类型的更改。如果你以串行而不是并行的方式进行计划中的更改,你可能会节省相当多的时间和精力。

对于跨越大量代码的主要重构,您应该强烈考虑串行工作:每个人都停止处理该代码区域,而一个人执行完整的重构。

如果你不能串行工作(可能是时间压力的原因),那么沟通预期的合并冲突至少可以帮助你在细节还记忆犹新的时候更快地解决问题。例如,如果一位同事在一周内进行了一系列破坏性的提交,你可以选择在那一周内每天一次或两次在该同事分支上合并/rebase。这样,如果你确实发现合并/rebase冲突,你可以比等待几周将所有内容合并在一起更快地解决它们。

提示五

如果你不确定合并,不要强迫它。

合并可能会让人感到不知所措,尤其是当有很多冲突文件并且冲突标记覆盖数百行时。通常,在估计软件项目时,我们没有足够的时间来处理开销项目,例如处理粗糙的合并,所以花几个小时剖析每个冲突感觉真的很拖累。

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

对于想要半手动解决合并冲突的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

完成合并。

您可以通过多种方式修复合并冲突,正如其他方法所详述的那样。

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

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

而不是:

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 ongit add .git commit # Then use the editor

]

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

git pull

git pull origin master.

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

相反我试着去做

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

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

git分支,分叉,获取,合并,rebase和克隆,有什么区别?

请参阅冲突是如何产生的或在Git中的git merge留档,以了解合并冲突标记是什么。

此外,如何解决冲突部分解释了如何解决冲突:

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

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

  • 解决冲突。Git将在工作树中标记冲突。将文件编辑成形状并将其git add到索引中。使用git commit密封交易。

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

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

  • 查看差异。git diff将显示一个三方差异,突出显示HEADMERGE_HEAD版本的更改。

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

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

您还可以在progit书籍第基本合并冲突节中阅读有关合并冲突标记以及如何解决它们的信息。

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

如果你不使用工具进行合并,首先将你的代码复制到外部:

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

它解决冲突,您可以复制代码。

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

步骤1:去分支

git checkout test

步骤2

git pull --rebase origin master

步骤3:如果有一些冲突,请转到这些文件进行修改。

步骤4:添加这些更改

git add #your_changes_files

步骤5

git rebase --continue

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

git push origin +test

步骤7:然后测试和主服务器之间没有冲突。您可以直接使用合并。

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(在这种情况下您合并到的分支)。

这将允许您查看两个分支分叉后文件中的提交内容。它通常会更容易解决冲突。

我总是遵循以下步骤来避免冲突。

  • git checkout master(来到主分支)
  • git pull(更新您的主机以获取最新代码)
  • git checkout -b mybranch(签出一个新的分支并开始处理该分支,以便您的master始终保持在主干的顶部。)
  • git add .git commitgit推送(更改后在本地分支上)
  • git checkout master(回到你的主人身边)

现在,您可以做同样的事情,并维护尽可能多的本地分支,并在必要时只需对您的分支执行git checkout即可同时工作。

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

  1. 检查Git状态:git状态

  2. 获取补丁集:获取文件(从您的Git提交中检查出正确的补丁)

  3. 签出一个本地分支(在我的例子中是tem1):git的校验结果

  4. 从master中提取最近的内容:#删除源主服务器

  5. 启动mergetool并检查冲突并修复它们…并使用当前分支检查远程分支中的更改:gitmergetool

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

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

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

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

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

合并冲突发生在同时对文件进行更改时。以下是如何解决它。

git CLI

以下是当你进入冲突状态时要做的简单步骤:

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

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

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

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

      但是,您必须小心,因为远程更改冲突是出于某种原因完成的。

      相关:在git中“我们的”和“他们的”的确切含义是什么?

    • 手动编辑有冲突的文件并查找<<<<</>>>>>之间的代码块,然后从=====的上方或下方选择版本。请参阅:冲突是如何呈现的

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

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

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

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

另请参阅:GitHub上的从命令行解决合并冲突

对于实用教程,请选中:场景5-Katacoda修复合并冲突

DiffMerge

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

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

DiffMerge

图片来源:DiffMerge(Linux截图)

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

git mergetool -t diffmerge .

macOS

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

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

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

#!/bin/shDIFFMERGE_PATH=/Applications/DiffMerge.appDIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMergeexec ${DIFFMERGE_EXE} --nosplash "$@"

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

  • -Alt-向上/下来跳转到上一个/下一个更改。
  • -Alt-/接受从左或右的更改

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

奖金:

在前面的答案中谈到拉取/获取/合并时,我想分享一个有趣且富有成效的技巧,

git pull --rebase

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

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

如果发生冲突,请使用

git mergetoolgit add conflict_filegit rebase --continue

查看详情:什么是"git拉-rebase"做什么?

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

git checkout . --ours

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

git checkout . --theirs

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

否则,您将不得不使用GUI合并工具逐个执行文件,例如合并工具是p4merge,或者编写您已经安装的任何文件的名称

git mergetool -t p4merge

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

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

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

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

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

顺便说一句,如果您安装Git扩展,在其安装向导中有一个选项来安装KDiF3。

然后设置Git配置以使用KDiff3作为其mergetool:

$ 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

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

这是KDiF3的样子:

在此输入图片描述

完成后,保存文件并将其转到下一个有冲突的文件,然后再做同样的事情,直到所有冲突都解决。

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

$ git mergetoolNo files need merging

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

完全接受我或他们的版本

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

git checkout --ours -- <filename>git add <filename>              # Marks conflict as resolvedgit 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 <filename>
  4. git commit -m "merged bla bla"

默认mergetool适用于命令行。如何使用命令行mergetool应该是一个单独的问题。

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

git mergetool -t meld

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

使用patience

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

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

git merge -s recursive -X patience other-branch

从留档:

With this option, merge-recursive spends a little extra time to avoidmismerges that sometimes occur due to unimportant matching lines(e.g., braces from distinct functions). Use this when the branches tobe 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>

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

有关如何使用它的快速介绍,请参阅这篇文章

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

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

这篇博客文章详细解释,但基础是通过UI“合并”两个分支时,您现在将看到一个“解决冲突”选项,该选项将带您到一个编辑器,允许您处理这些合并冲突。

在此处输入图片描述

具体分为三个步骤:

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

     git status
  2. 检查文件,您会在其中找到标记为

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

     git add solved_conflicts_filesgit commit -m 'merge msg'
git fetch <br>git checkout **your branch**<br>git rebase master<br>

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

您可以按照此链接检查如何修复文件中的冲突。

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

现在一切都很好,你会在Gerrit中找到你的承诺。

对于那些使用Visual Studio的人(在我的情况下为Visual Studio 2015

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

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

    git签出target_branch

    git合并source_branch

  3. 然后在Visual Studio中打开项目并转到Team Explorer→。现在有一条消息说合并待定,冲突文件列在消息的正下方。

  4. 单击冲突的文件,您将可以选择合并比较获取源代码拿下Target。Visual Studio中的合并工具非常易于使用。

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

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

它将显示所有冲突,如下所示:

A_MBPro:测试anu$git合并源/自动合并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中打开该文件。它将包含以下部分

  <<<<<<< HEADpublic void testMethod() {}=======public void testMethod() { ...}>>>>>>> origin/<remotebranch>

其中HEAD是本地分支上的更改,而原始/<远程分支>是来自远程分支的更改。这里保留您需要的东西并删除您不需要的东西。之后,正常的步骤应该就可以了。那就是

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

我遵循下面的过程。

修复合并冲突的过程:

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

  2. 当您从目标获取最新信息时,现在通过删除这些额外字符在IDE中手动解决冲突。

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

  4. git add完成时,执行git commit来提交更改。

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

这就是它,如果您使用的是比特桶或GitHub,您将在拉取请求中看到它被解决。

这个答案是为像我这样喜欢在编辑器中执行所有操作的Vim用户添加一个替代方案。


太长别读

在此输入图片描述


Tpope为Vim提出了这个名为逃犯的很棒的插件。安装后,您可以运行:Gstatus来检查有冲突的文件,并运行:Gdiff以三方合并的方式打开Git。

一旦进入三路合并,逃犯将让您以以下方式获得您正在合并的任何分支的更改:

  • :diffget //2,从原始(HEAD)分支获取更改:
  • :diffget //3,从合并分支获取更改:

完成合并文件后,在合并的缓冲区中键入:Gwrite

Vimcast发布了一个很棒的视频,详细解释了这些步骤。

如果还没有,请尝试使用Visual Studio Code进行编辑。

尝试合并(并在合并冲突中着陆)后,Visual Studio Code会自动检测合并冲突。

它可以通过显示对原始文件所做的更改以及您是否应该接受incoming

current change(表示合并前的原始版本)'。

它帮助了我,也可以为你工作!

PS:仅当您使用代码和Visual Studio Code配置Git时,它才会工作。

用于Visual Studio代码的GitLens

您可以尝试GitLens for Visual Studio Code。主要功能是:

3.轻松解决冲突

我已经喜欢这个功能了:

在此输入图片描述

2.当前线路责任。

在此输入图片描述

3.阴沟责备

在此输入图片描述

4.状态栏责备

在此输入图片描述

还有很多功能。您可以检查它们这里

我正在使用Microsoft的Visual Studio Code来解决冲突。它使用起来非常简单。我在工作区中保持我的项目打开。它检测并突出显示冲突。此外,它提供了GUI选项来选择我想从HEAD或传入中保留的任何更改。

在此输入图片描述

如果您只想恢复远程主机,则

git reset --hard origin/master

警告:所有本地更改都将丢失,https://stackoverflow.com/a/8476004/11769765.

我喜欢使用WinMerge(免费工具)进行完整的整个目录树比较/合并以及完整目录树比较的单个文件比较/合并。

Git合并冲突告诉您,您的拉取请求将撤消/丢失/覆盖同事的更改,通常是因为您的内容副本不够新。

解决的步骤可以是:

  • 将源的另一个新克隆带到新命名的文件夹中,
  • 使用WinMerge比较您的内容和最新的内容以了解冲突,
  • 对于您自己和您的同事更改的导致Git Merge冲突的文件,请查看您的同事添加/更改/删除的行与您添加/更改/删除的代码行相比。
  • 使用WinMerge左/右代码部分移动箭头以确保您的同事的工作在您的文件副本中,并且您不会破坏他们的工作。

也就是说,除了手动查看每个人对同一个源文件所做的事情之外,没有解决Git合并冲突的神奇方法。

我就是这么想的。

注意:WinMerge创建. bak文件…并且您不希望它们复制到源代码控制AzOps、TFS等,因此如果您确定已正确完成编辑,请删除. bak文件。

好吧,所有已经给出的答案似乎都解释了您可以使用哪些工具来检测合并冲突或如何启动合并请求……

然而,你的问题的答案既简单又令人沮丧。合并冲突几乎总是手动解决。如果你使用像GitLab这样的工具,GUI可能会帮助你找到两个代码版本的差异,但在一天结束时,你必须决定哪一行应该保留,哪一行应该删除。

一个简单的例子:程序员A和程序员B都将相同的(不同修改的)文件推送到远程存储库。程序员A打开一个合并请求,GitLab突出显示了两个版本之间发生冲突的几行代码。现在由程序员A和B来决定谁在这些特定行中编写了更好的代码。他们必须做出妥协。

我明白合并冲突是什么,但是当我看到git diff的输出时,起初对我来说它看起来像是无稽之谈:

git diff++<<<<<<< HEAD+ display full last name boolean in star table++=======+ users viewer.id/star.id, and conversation uses user.id+++>>>>>>> feat/rspec-tests-for-cancancan

但是这里帮助了我:

  • #0和#1之间的所有内容都在一个文件中

  • #0和#1之间的所有内容都是另一个文件中的内容

  • 所以从字面上看,你所要做的就是打开带有合并冲突的文件,并从任一分支中删除这些行(或者只是让它们相同),merge将立即成功。问题解决了!