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.
# 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
(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
<<<<<<<
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.
>>>>>>>
30 回答
我总是按照以下步骤来避免冲突 .
git checkout master(来到master分支)
git pull(更新你的主人以获取最新代码)
git checkout -b mybranch(签出新的分支并开始在该分支上工作,以便主人始终保持在主干之上 . )
git add . 和git commit AND git push(在你的更改后在你的本地分支上)
git checkout master(回到你的主人那里 . )
现在你可以做同样的事情并维护你想要的许多本地分支机构并同时工作我只需要在你的分支机构进行git checkout .
试试:
git mergetool
它会打开一个GUI,引导您完成每个冲突,然后您可以选择合并方式 . 有时它需要稍后进行一些手工编辑,但通常它本身就足够了 . 这肯定比手工做整件事要好得多 .
根据@JoshGlover评论:
除非您安装GUI,否则该命令不一定会打开GUI . 为我运行
git mergetool
导致vimdiff
被使用 . 您可以安装以下工具之一,而不是使用它:meld
,opendiff
,kdiff3
,tkdiff
,xxdiff
,tortoisemerge
,gvimdiff
,diffuse
,ecmerge
,p4merge
,araxis
,vimdiff
,emerge
.以下是使用
vimdiff
解决合并冲突的示例过程 . 基于this linkStep 1 :在终端中运行以下命令
这会将vimdiff设置为默认合并工具 .
Step 2 :在终端中运行以下命令
Step 3 :您将看到以下格式的vimdiff显示
这4个观点是
您可以使用
ctrl+w
在这些视图之间导航 . 您可以使用ctrl+w
然后j
直接到达MERGED视图 .有关更多信息vimdiff navigation here和here
Step 4 . 您可以通过以下方式编辑MERGED视图
如果您想从REMOTE获得更改
如果您想从BASE获得更改
如果您想从LOCAL获得更改
Step 5 . 保存,退出,提交和清理
:wqa
保存并退出vigit commit -m "message"
git clean
删除diff工具创建的额外文件(例如* .orig) .确定哪些文件存在冲突(Git应该告诉你) .
打开每个文件并检查差异; Git划定了他们 . 希望很明显每个块的哪个版本要保留 . 您可能需要与提交代码的开发人员讨论它 .
解决文件
git add the_file
中的冲突后 .一旦解决了 all 冲突,请执行
git rebase --continue
或Git在完成后要执行的任何命令 .如果要从分支(测试)合并到主服务器,可以按照以下步骤操作:
第1步:转到分支机构
第2步:
git pull --rebase origin master
步骤3:如果存在一些冲突,请转到这些文件进行修改 .
第4步:添加这些更改
第5步:
git rebase --continue
步骤6:如果仍有冲突,请再次返回步骤3 . 如果没有冲突,请执行以下操作:
git push origin +test
第7步:然后测试和主人之间没有冲突 . 您可以直接使用合并 .
耐心等待
我很惊讶没有人谈到使用合并递归策略使用
patience
来解决冲突 . 对于大合并冲突,使用patience
为我提供了良好的结果 . 我们的想法是尝试匹配块而不是单独的线 .例如,如果更改程序的缩进,默认的Git合并策略有时会匹配属于不同函数的单个大括号
{
. 使用patience
可以避免这种情况:从文档:
与共同祖先的比较
如果你有合并冲突,并希望看到修改其分支机构当别人脑子里想的是什么,它有时更容易及其分支机构直接与共同祖先(而不是我们的分公司)进行比较 . 为此你可以使用
merge-base
:通常,您只想查看特定文件的更改:
我按照以下流程 .
修复合并冲突的过程:
首先,从要合并的目标分支中提取最新信息
git pull origin develop
当您从目标获取最新信息时,现在可以通过删除这些额外字符在IDE中手动解决冲突 .
做一个
git add
这些编辑的文件添加到git的队列,以便它可以commit
和push
到同一分支您正在使用 .完成
git add
后,执行git commit
提交更改 .现在按
git push origin HEAD
将更改推送到您的工作分支这就是它,如果您使用的是Bitbucket或GitHub,您将在拉取请求中看到它已解决 .
对于那些使用Visual Studio的人(在我的情况下为2015)
在VS中关闭项目 . 特别是在大型项目中,VS在使用UI进行合并时往往会吓坏 .
在命令提示符下执行合并 .
git checkout target_branch
git merge source_branch
然后在VS中打开项目并转到团队资源管理器 - >分支 . 现在有一条消息说Merge正在等待,并且消息下方列出了冲突的文件 .
单击冲突的文件,您将可以选择合并,比较,获取源,获取目标 . VS中的合并工具非常易于使用 .
似乎并不总是对我有用,并且通常最终会显示两个分支之间不同的每个提交,即使使用
--
将路径与命令分开也会发生这种情况 .我解决这个问题的方法是在一次运行中打开两个命令行
而在另一方面
将
$MERGED_IN_BRANCH
替换为我合并的分支,并将[path]
替换为冲突的文件 . 此命令将以补丁形式记录(..
)两次提交之间的所有提交 . 如果你把一方留空,就像上面的命令一样,git会自动使用HEAD
(在这种情况下你要合并的分支) .这将允许您查看两个分支在分叉后进入文件的提交 . 它通常可以更容易地解决冲突 .
解决冲突的更安全的方法是使用git-mediate(此处建议的常见解决方案非常容易出错) .
有关如何使用它的快速介绍,请参见this post .
查看Stack Overflow问题Aborting a merge in Git中的答案,特别是Charles Bailey's answer,其中显示了如何查看有问题的文件的不同版本,例如,
如果您经常进行小型提交,那么首先查看
git log --merge
的提交注释 . 然后git diff
将显示冲突 .对于涉及多行的冲突,它会在外部GUI工具中进行 . 我喜欢opendiff - Git也支持vimdiff,gvimdiff,kdiff3,tkdiff,meld,xxdiff,emerge开箱即用,你可以安装其他人:
git config merge.tool "your.tool"
将设置你选择的工具然后git mergetool
合并失败后会显示你的差异上下文 .每次编辑文件以解决冲突时,
git add filename
将更新索引,您的差异将不再显示 . 处理完所有冲突并且他们的文件已经__7107_ -ed时,git commit
将完成您的合并 .CoolAJ86的答案总结了几乎所有东西 . 如果您在同一段代码中的两个分支都有更改,则必须进行手动合并 . 在任何文本编辑器中打开冲突文件,您应该看到以下结构 .
以您希望新代码的方式选择其中一个替代方案或两者的组合,同时删除等号和尖括号 .
奖金:
在上述答案中谈到拉/取/合并时,我想分享一个有趣且富有成效的技巧,
git pull --rebase
上面的命令是我git生活中最有用的命令,节省了大量的时间 .
在将新提交的更改推送到远程服务器之前,请尝试
git pull --rebase
而不是git pull
和手动merge
,它将自动同步最新的远程服务器更改(使用提取合并),并将您的本地最新提交放在git log的顶部 . 无需担心手动拉/合并 .如果发生冲突,请使用
查找详细信息:http://gitolite.com/git-pull--rebase
这是一个可能的用例,从顶部:
你要做一些改变,但是哎呀,你不是最新的:
所以你得到最新的并再试一次,但是有冲突:
所以你决定看一下这些变化:
哦,我,我的,上游改变了一些事情,但只是为了使用我的改变......不......他们的改变......
然后我们尝试最后一次
当当!
如果您使用intelliJ作为IDE尝试将父级合并到您的分支
它将显示所有这样的冲突
现在请注意,文件TestClass.java在intelliJ中显示为红色,同时git status将显示
在intelliJ中打开文件,它将包含部分
其中HEAD是您本地分支上的更改,而原始/是远程分支的更改 . 在这里保留你需要的东西,并删除你不需要的东西 . 之后正常的步骤应该做 . 那是
我要么完全想要我或他们的版本,要么想要审查个别更改并决定每个更改 .
Fully accept my or theirs version :
接受我的版本(本地,我们的):
接受他们的版本(远程,他们的):
如果你想做 for all conflict files 运行:
要么
Review all changes and accept them individually
git mergetool
查看更改并接受每个版本的任一版本 .
git add <filename>
git commit -m "merged bla bla"
默认
mergetool
适用于 command line . 如何使用命令行mergetool应该是一个单独的问题 .您也可以为此安装 visual tool ,例如
meld
然后跑它将打开本地版本(我们的),"base"或"merged"版本(合并的当前结果)和远程版本(他们的) . 完成后保存合并版本,再次运行
git mergetool -t meld
直到获得"No files need merging",然后转到步骤3和4 .您可以通过多种方式修复合并冲突有详细的 .
我认为真正的关键是了解变化如何与本地和远程存储库一起流动 . 关键是要了解跟踪分支 . 我发现我认为跟踪分支是我本地的实际文件目录和定义为原点的远程之间的“中间缺失的部分” .
我个人习惯了两件事来帮助避免这种情况 .
代替:
这有两个缺点 -
a)添加所有新的/更改的文件,其中可能包含一些不需要的更改 .
b)您无法先查看文件列表 .
所以相反,我做:
通过这种方式,您可以更加深思熟虑地添加哪些文件,并且还可以在使用编辑器查看消息时查看列表并进行更多思考 . 当我使用全屏编辑器而不是
-m
选项时,我发现它也改进了我的提交消息 .[更新 - 随着时间的推移,我已经切换到:
]
另外(和你的情况更相关),我尽量避免:
要么
因为pull意味着合并,如果您在本地进行了不希望合并的更改,则很容易就会出现合并代码和/或合并冲突,因为这些代码不应该合并 .
相反,我尝试做
您可能还会发现这有用:
git branch, fork, fetch, merge, rebase and clone, what are the differences?
合并冲突可能发生在不同的情况:
运行"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 configs使用Kdiff作为其mergetool:
(请记住用Kdiff exe文件的实际路径替换路径 . )
然后,每次遇到合并冲突时,您只需运行此命令:
然后它打开Kdiff3,并首先尝试自动解决合并冲突 . 大多数冲突将自发解决,您需要手动修复其余冲突 .
这是Kdiff3的样子:
然后,一旦完成,保存文件,它将转到下一个冲突的文件,然后再次执行相同的操作,直到所有冲突都得到解决 .
要检查是否所有内容都已成功合并,只需再次运行mergetool命令,您应该得到以下结果:
在此步骤中,您将尝试使用您喜欢的IDE修复冲突
您可以按照此链接检查以解决文件中的冲突
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
现在一切都很好,你会发现你在gerrit中的承诺
我希望这对每个人都有所帮助 .
请按照以下步骤修复Git中的合并冲突:
检查Git状态: git status
获取补丁集: git fetch (从Git提交中检出正确的补丁)
签出本地分支(我的示例中为temp1):_ git checkout -b temp1
从master中拉出最近的内容: git pull --rebase origin master
启动mergetool并检查冲突并修复它们...并使用当前分支检查远程分支中的更改: git mergetool
再次检查状态: git status
删除mergetool本地创建的不需要的文件,通常mergetool创建带* .orig扩展名的额外文件 . 请删除该文件,因为它只是重复文件并在本地修复更改并添加正确版本的文件 . git add #your_changed_correct_files
再次检查状态: git status
将更改提交到相同的提交ID(这可以避免新的单独补丁集):_ git commit --amend
推送到主分支: git push (到您的Git存储库)
如果存在合并冲突,请修复它们 . 然后,通过运行继续rebase进程:
git rebase –-continue
修复后,您可以提交并将本地分支推送到远程分支
当同时对文件进行更改时,会发生合并冲突 . 这是如何解决它 .
git CLI
以下是进入冲突状态时要执行的操作的简单步骤:
请注意冲突文件列表:
git status
(在Unmerged paths
部分下) .通过以下方法之一单独解决每个文件的冲突:
使用GUI解决冲突:
git mergetool
(最简单的方法) .要接受远程/其他版本,请使用:
git checkout --theirs path/file
. 这将拒绝您对该文件所做的任何本地更改 .要接受本地/我们的版本,请使用:
git checkout --ours path/file
但是你要小心,因为远程改变冲突是出于某种原因 .
相关:What is the precise meaning of "ours" and "theirs" in git?
手动编辑冲突的文件并查找
<<<<<
/>>>>>
之间的代码块,然后从=====
上方或下方选择版本 . 见:How conflicts are presented .路径和文件名冲突可以通过
git add
/git rm
解决 .最后,使用以下命令查看准备提交的文件:
git status
.如果你仍然有
Unmerged paths
下的任何文件,并且你确实手动解决了冲突,那么让Git知道你解决了它:git add path/file
.git commit -a
并像往常一样推送到远程 .另请参阅:GitHub上的Resolving a merge conflict from the command line
DiffMerge
我已成功使用DiffMerge,它可以在Windows,macOS和Linux / Unix上直观地比较和合并文件 .
它以图形方式显示3个文件之间的变化,它允许自动合并(在安全的情况下),并完全控制编辑生成的文件 .
图像源:DiffMerge(Linux截图)
只需下载并在repo中运行:
macOS
在macOS上,您可以通过以下方式安装
并且可能(如果没有提供)你需要在PATH中放置以下额外的简单包装器(例如
/usr/bin
):然后您可以使用以下键盘快捷键:
⌘-Alt-Up / Down跳转到上一个/下一个更改 .
⌘-Alt-Left / Right接受来自左侧或右侧的更改
或者,您可以使用opendiff(Xcode Tools的一部分),它允许您将两个文件或目录合并在一起以创建第三个文件或目录 .
对于想要半手动解决合并冲突的Emacs用户:
显示需要解决冲突的所有文件 .
逐个打开每个文件,或者一次全部打开:
访问需要在Emacs中编辑的缓冲区时,请键入
这将打开三个缓冲区(我的,他们的和输出缓冲区) . 按'n'(下一个区域),'p'(预视区域)进行导航 . 按'a'和'b'分别将我或他们的区域复制到输出缓冲区 . 和/或直接编辑输出缓冲区 .
完成后:按'q' . Emacs会询问您是否要保存此缓冲区:是的 . 完成一个缓冲区后,通过从teriminal运行解决它:
完成所有缓冲区类型后
完成合并 .
请参阅How Conflicts Are Presented或在Git中使用
git merge
文档来了解合并冲突标记是什么 .此外,How to Resolve Conflicts部分解释了如何解决冲突:
您还可以在Pro Git book部分Basic Merge Conflicts中阅读有关合并冲突标记以及如何解决它们的信息 .
这个答案是为那些喜欢在编辑器中做所有事情的VIM用户添加一个替代方案 .
TL; DR
Tpope想出了一个名为fugitive的VIM插件 . 安装完成后,您可以运行
:Gstatus
来检查有冲突的文件,并运行:Gdiff
以3方式合并打开Git .一旦进入3-way合并,fugitive将允许您以下列方式获取要合并的任何分支的更改:
:diffget //2
,从原始(HEAD)分支获取更改::diffget //3
,从合并分支获取更改:完成合并文件后,键入
:Gwrite
在合并缓冲区中 . Vimcasts发布了一个很好的video详细解释了这一步骤 .我发现合并工具很少帮助我理解冲突或解决方案 . 我通常更成功地在文本编辑器中查看冲突标记并使用git log作为补充 .
以下是一些提示:
提示一
我发现的最好的事情是使用“diff3”合并冲突风格:
git config merge.conflictstyle diff3
这会产生如下冲突标记:
中间部分是共同祖先的样子 . 这很有用,因为您可以将它与顶部和底部版本进行比较,以更好地了解每个分支上的更改内容,从而更好地了解每个更改的目的 .
如果冲突只有几行,这通常会使冲突非常明显 . (知道如何解决冲突是非常不同的;你需要知道其他人正在做什么 . 如果你感到困惑,最好是把那个人叫到你的房间,这样他们就能看到你在看什么在 . )
如果冲突时间较长,那么我会将三个部分中的每一部分剪切并粘贴到三个单独的文件中,例如“我的”,“普通”和“他们的” .
然后我可以运行以下命令来查看导致冲突的两个差异:
这与使用合并工具不同,因为合并工具也将包括所有非冲突的差异 . 我觉得这会分散注意力 .
提示二
有人已经提到了这一点,但了解每个差异背后的意图通常对于了解冲突来自何处以及如何处理它非常有帮助 .
这显示了在共同祖先和要合并的两个头之间触及该文件的所有提交 . (因此它不包括在合并之前已存在于两个分支中的提交 . )这有助于您忽略明显不是当前冲突因素的差异 .
提示三
使用自动化工具验证您的更改 .
如果您有自动化测试,请运行它们 . 如果您有一个lint,请运行它 . 如果它_____7071_ t打破任何东西 . (哎呀,即使没有冲突的合并也会破坏工作代码 . )
提示四
未雨绸缪;与同事沟通 .
提前规划并了解其他人正在进行的工作可以帮助防止合并冲突和/或帮助他们提前解决 - 而细节仍然是新鲜的 .
例如,如果您知道您和另一个人都在进行不同的重构,这两个重构都会影响同一组文件,那么您应该提前相互交谈并更好地了解每个人的变化类型 . 制造 . 如果您按顺序而不是并行地执行计划的更改,则可能会节省大量时间和精力 .
对于跨越大量代码的主要重构,您应该强烈考虑连续工作:当一个人执行完整的重构时,每个人都停止在代码的该区域工作 .
如果你不能连续工作(由于时间压力,也许),那么沟通预期的合并冲突至少可以帮助你更快地解决问题,同时细节仍然是新鲜的 . 例如,如果同事在一周的时间内进行了一系列破坏性的提交,您可以选择在该周期间每天一次或两次合并/重组该同事分支 . 这样,如果你确实发现了合并/ rebase冲突,你可以比等待几周将所有内容合并成一个大块的更快地解决它们 .
提示五
如果您不确定合并,请不要强迫它 .
合并可能会让人感到压力,特别是当存在大量冲突文件且冲突标记覆盖数百行时 . 通常在评估软件项目时,我们没有足够的时间来处理开销项目,例如处理粗糙的合并,因此花费几个小时来解决每个冲突感觉真的很麻烦 .
从长远来看,提前规划并了解其他人正在开展的工作是预测合并冲突并准备好在更短的时间内正确解决冲突的最佳工具 .
截至2016年12月12日,您可以合并分支机构和 resolve conflicts on github.com
因此,如果您不想使用命令行或此处提供的任何第三方工具,请使用GitHub的本机工具 .
This blog post详细解释,但基本原理是通过UI在'merging'两个分支上,您现在将看到'resolve conflicts'选项,它将带您到编辑器,允许您处理这些合并冲突 .
有3个步骤:
简单地说,如果您清楚地了解其中一个存储库中的更改并不重要,并希望解决所有更改以支持另一个存储库,使用:
解决有利于 your repository 的变化,或
解决有利于 other or the main repository 的变化 .
否则你将不得不使用GUI合并工具逐个浏览文件,比如说合并工具是
p4merge
,或者写任何一个's name you' ve已安装完成文件后,您必须保存并关闭,因此下一个文件将打开 .
如果您还没有,请尝试使用Visual Studio代码进行编辑 . 它的作用是在您尝试合并(并在合并冲突中登陆)之后.VS代码自动检测合并冲突 .
它可以通过显示对原始更改的内容来帮助您,并且您是否应该接受
incoming
或current change
(意思是合并之前的原始版本)'?它对我有帮助,它也适合你!
PS:只有在使用代码和Visual Studio Code配置git时才会起作用 .