我想解决Git存储库中的合并冲突。
该怎么做?

评论

以下博客文章似乎提供了一个很好的示例,说明了如何处理与Git的合并冲突,这应该使您朝正确的方向前进。处理和避免Git中的冲突

您可以配置合并工具(kdiff3jebaird.com/2013/07/08/…),然后使用git mergetool。在大型开发人员团队中工作时,您总是会遇到合并冲突。

不要忘记,可以通过定期下游合并来缓解大多数合并冲突!

另请参阅git-tower.com/learn/git/ebook/command-line/tools-services/…

一个令人着迷的问题:在2008年被问到100%开放时,它到底是什么(关于GUI?关于git命令吗?关于语义?关于推/拉还是只是一般冲突?),根本没有任何暗示。 30个答案,所有答案(据快速浏览显示)或多或少地针对不同的diff3和合并工具进行,没有一个被接受。投票最多的答案提到的命令甚至在默认的git安装中都无法立即使用。今天(2017年),我成功进入了SE的起始页,并获得了130万的观看次数和成千上万的投票。令人着迷。

#1 楼

试试:git mergetool
它会打开一个GUI,逐步引导您解决每个冲突,然后您可以选择合并方式。有时此后需要进行一些手动编辑,但通常仅此一项就足够了。这肯定比手工完成整个过程要好得多。
根据@JoshGlover注释:
除非安装一个GUI,否则该命令不一定要打开GUI。对我来说运行git mergetool导致使用了vimdiff。您可以安装以下工具之一来代替使用它:meldopendiff
kdiff3tkdiffxxdifftortoisemergegvimdiffdiffuse
ecmergep4mergearaxisvimdiff

下面是使用emerge解决合并冲突的示例过程。基于此链接
步骤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 –合并结果,这就是保存在存储库中的内容

您可以使用ctrl + w在这些视图之间导航。您可以使用ctrl + w和j直接进入MERGED视图。
此处和此处有关vimdiff导航的更多信息
步骤4。您可以按以下方式编辑MERGED视图
如果要从REMOTE获取更改
:diffg RE  

如果要从BASE获取更改
:diffg BA  

如果要从LOCAL
获取更改
:diffg LO 

步骤5。保存,退出,提交和清理
vimdiff保存并退出vi
:wqa
git commit -m "message"删除由diff工具创建的多余文件(例如* .orig)。

评论


仅供参考,如果您要一次合并大量文件,则可以使用git mergetool -y保存一些击键。

–davr
2010年6月17日23:32

好吧,除非您安装一个GUI,否则不一定打开GUI。为我运行git mergetool导致使用了vimdiff。您可以安装以下工具之一来代替使用它:融合opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiffdiffuse ecmerge p4merge araxis vimdiff出现。

–乔什·格洛弗(Josh Glover)
2011年5月11日14:00

好点的乔希。在ubuntu上,我的运气最好,它的三向合并显示也不错。在OSX上,git选择了一个不错的默认值。

– Peter Burns
2011年5月24日5:08

这打开了KDiff3。我绝对不知道如何使用。

–大卫·默多克(David Murdoch)
2011-6-10 18:46

您现在也可以使用Beyond Compare 3(git mergetool -t bc3)。

– AzP
2012年8月30日14:59



#2 楼

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

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

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.


Ta-da!

评论


这非常有用,因为我在二进制文件(艺术资产)中有很多合并错误,合并这些错误似乎总是失败,因此我需要始终用新文件覆盖它,而不是“合并”

–石油
2011年6月8日17:39

小心!我们和他们的含义相反。 --ours ==遥控器。 -他们的==当地的。参见git merge --help

–mmell
2013年3月4日22:56



就我而言,我确认--theirs =远程存储库,--ours =我自己的本地存储库。它与@mmell注释相反。

– Aryo
13年6月22日在12:59

@mmell显然,仅在重新建立基础上。看到这个问题

– Navin
13年10月10日在6:19



伙计们,“我们的”和“他们的”与您是否要合并还是变基础有关。如果要合并,则“我们的”是指您要合并的分支,而“他们的”是您要合并的分支。当您进行基础调整时,“我们的”是指您要进行基础调整的提交,而“其”指的是您要重新设置的提交。

–user456814
2014年5月26日下午4:27

#3 楼

我发现合并工具很少能帮助我理解冲突或解决方案。通常,我在文本编辑器中查看冲突标记并使用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.
>>>>>>>


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

如果冲突只有几行,那么通常会使冲突非常明显。 (知道如何解决冲突是非常不同的;您需要了解其他人的工作。如果您感到困惑,最好将这个人叫到您的房间,以便他们可以看到您的情况。 at。)

如果冲突时间更长,那么我将三个部分分别剪切并粘贴到三个单独的文件中,例如“ mine”,“ common”和“ theirs”。

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

diff common mine
diff common theirs


这与使用合并工具不同,因为合并工具也将包含所有非冲突的diff块。我发现这很让人分心。

技巧二

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

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


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

提示三

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

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

技巧四

提前计划;与同事进行沟通。

提前计划并了解其他人正在做什么,可以帮助防止合并冲突和/或帮助及早解决这些冲突-尽管细节仍在脑海中。

例如,如果您知道自己和另一个人都在进行不同的重构,而这将影响同一组文件,则应该提前进行交谈,以更好地理解你们每个人都在进行哪些类型的更改。如果以串行方式而不是并行方式执行计划的更改,则可以节省大量时间和精力。

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

如果您不能连续工作(也许是由于时间压力),那么就预期的合并冲突进行交流至少可以帮助您在细节仍在脑海中的同时更快地解决问题。例如,如果某个同事在一个星期的时间内进行了一系列破坏性的提交,则您可以选择在该一周中每天一次或两次在该同事分支上进行合并/重新设置。这样,如果您发现合并/重新设置冲突,则比等待几周一次将所有内容合并成一个大块时可以更快地解决它们。

技巧五

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

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

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

评论


diff3选项是合并功能的重要功能。我遇到的唯一一个显示它的GUI是Perforce的p4merge,它可以与Perforce的其他工具(我没有用过,但是听到过抱怨)分开安装和使用。

– alxndr
2014年5月1日22:15

重新尝试导致合并冲突后:$ git log --merge -p build.xml输出:致命:--merge没有MERGE_HEAD?

– Ed Randall
16年6月17日在9:15



如果我对branch1的一个文件进行了更改,而在branch2中删除了该文件怎么办?我该如何解决合并冲突?有什么办法可以使用git通过保留一个分支的更改来合并它们?

–蜂蜜
17年1月21日在14:48

git config merge.conflictstyle diff3-谢谢您,先生。这真是太神奇了,这使我摆脱了寻找(并支付$$)好的3方式合并GUI的负担。 IMO这样做更好,因为它显示了公共祖先以及本地/远程,并显示了没有GUI的(AFAIK)最后提交日志行。提交肯定可以帮助您确定哪些代码属于哪个分支。

–ffxsam
17年4月4日在16:00

我发现有时diff3冲突样式会导致大量的diff块,这些块在很大程度上是相同的,而默认值会产生更小,更易于管理的块。不幸的是,我没有可用于错误报告的复制器。但是,如果遇到此问题,您可以考虑暂时关闭该选项。

–戴夫·亚伯拉罕
17年7月2日,下午3:31

#4 楼


确定哪些文件存在冲突(Git会告诉您)。
打开每个文件并检查差异; Git将它们划分边界。希望可以很清楚地看到每个块的版本。您可能需要与提交代码的其他开发人员讨论。
解决文件git add the_file中的冲突后。
解决所有冲突后,请执行git rebase --continue或其他命令
Git完成后说要做。


评论


@Justin认为Git是跟踪内容而不是跟踪文件。然后很容易看到您更新的内容不在存储库中,需要添加。这种思维方式也解释了Git为什么不跟踪空文件夹的原因:尽管从技术上讲它们是文件,但没有任何要跟踪的内容。

–加雷斯
2010-10-12 9:17

内容存在,因为存在2个版本的内容而发生冲突。因此,“ git add”听起来不正确。如果您只想在冲突解决后提交一个文件,则它不起作用(git add,git commit)(“致命:合并期间无法进行部分提交”。)

– Dainius
2011年9月14日上午9:19

是的,从技术上讲,这可以回答所提出的问题,但对不起,这不是可用的答案。使一个分支与另一个分支相同有什么意义?当然合并会产生冲突。

– Thufir
2012年8月9日下午5:56

Thulfir:谁说过使一个分支与另一个分支相同的话?在不同的情况下,您需要合并,而无需“使一个分支与另一个分支相同”。一种是当您完成开发分支后,想要将其更改合并到主分支中;之后,可以删除开发分支。另一个是当您想重新建立开发分支的基础时,以便于最终最终合并到主数据库中。

– Teemu Leisti
2012年9月21日在8:50



@JustinGrant git在索引中添加阶段文件;它不会向存储库添加任何内容。 git commit将内容添加到存储库。这种用法对于合并很有意义-合并会自动暂存所有可以自动合并的更改;您有责任合并其余的更改,并在完成后将这些更改添加到索引中。

– Mark E. Haase
2012年10月17日15:13



#5 楼

同时更改文件时,会发生合并冲突。这是解决问题的方法。


git CLI

当您陷入冲突状态时,可以执行以下简单步骤:


请注意以下冲突文件列表:git status(在Unmerged paths部分下)。

通过以下方法之一分别解决每个文件的冲突:


使用GUI解决冲突:git mergetool(最简单的方法)。
要接受远程版本或其他版本,请使用:git checkout --theirs path/file。这将拒绝您对该文件所做的任何本地更改。

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

,但是您要小心,因为远程更改会发生冲突是由于某种原因。
相关:git中“我们的”和“他们的”的确切含义是什么?

手动编辑冲突的文件并查找<<<<< / >>>>>之间的代码块,然后从=====的上方或下方选择版本。请参阅:如何显示冲突。
可以通过git add / git rm解决路径和文件名冲突。



最后,使用以下命令查看准备提交的文件:git status

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

如果所有冲突都是成功解决后,通过以下方法提交更改:git commit -a并像往常一样推送到远程。

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

有关实际教程,请检查:方案5-Katacoda修复合并冲突。

DiffMerge

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

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



图像来源:DiffMerge(Linux屏幕快照)

只需下载并在仓库中运行即可:

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/向下跳到上一个/下一个更改。

⌘-Alt-Left/ Right接受从左或右的更改

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

#6 楼

请查看“堆栈溢出”问题中的答案,特别是中止合并中的合并,尤其是Charles Bailey的答案,该答案显示了如何查看有问题的文件的不同版本,例如

 # 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”选项-它允许您将不同的苍蝇提取回工作区

– qneill
2015年2月5日在22:06

这救了我。分别查看每个文件可以让我记住在每个分支中要做什么。然后,我可以决定选择。

–罗默
16年5月14日在21:59

#7 楼

如果您要进行频繁的小提交,请先使用git log --merge查看提交注释。然后,git diff将向您显示冲突。

对于涉及多行的冲突,更容易查看外部GUI工具中发生的情况。我喜欢opendiff-Git还支持vimdiff,gvimdiff,kdiff3,tkdiff,meld,xxdiff,可以直接安装,还可以安装其他工具:git config merge.tool "your.tool"将设置您选择的工具,合并失败后git mergetool将显示差异。

每次编辑文件以解决冲突时,git add filename都会更新索引,并且您的差异将不再显示该索引。处理完所有冲突并且对其文件进行git add -ed处理后,git commit将完成您的合并。

评论


使用“ git add”是这里的真正把戏。您甚至可能不想提交(也许想隐藏),但是必须执行“ git add”才能完成合并。我认为mergetool会为您执行添加操作(尽管不在手册页中),但是如果您手动进行合并,则需要使用“ git add”来完成它(即使您不想提交)。

–布伦特·布拉德本(Brent Bradburn)
2010-10-25 9:37

#8 楼

请参阅冲突的呈现方式,或者在Git中查看git merge文档以了解什么是合并冲突标记。
此外,如何解决冲突部分介绍了如何解决冲突:发生冲突时,您可以做两件事:


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


解决冲突。 Git将标记工作树中的冲突。将文件编辑为形状,然后将其git add索引。使用git commit可以完成交易。


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


使用mergetool。 git 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版本。




您还可以在中阅读有关合并冲突标记以及如何解决它们的信息。 Pro Git的“基本合并冲突”部分。

#9 楼

我或者想要完整了解我的版本,或者想要查看每个更改并为每个更改决定。

完全接受我的版本:

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

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


查看所有更改并接受它们单独


git mergetool
查看更改并接受每个版本中的任何一个版本。
git add <filename>
git commit -m "merged bla bla"

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

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

git mergetool -t meld


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

评论


此命令:git checkout --theirs-<文件名>将所有文件更改为它们的文件,而不仅仅是<文件名>

–多纳托
18年6月26日下午1:00

其实我错了。这只会更新指定的文件。

–多纳托
18年6月26日在1:23

#10 楼

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

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


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

打开每个文件一次或一次全部归档:

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


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

ALT+x vc-resolve-conflicts


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

完成后:按'q'。 Emacs询问您是否要保存此缓冲区:是。
完成缓冲区后,通过从末尾运行将其标记为已解析:

git add FILENAME


完成后使用所有缓冲区类型

git commit


完成合并。

#11 楼

奖励:
说到以上答案中的pull / fetch / merge,我想分享一个有趣且富有成效的技巧,
git pull --rebase
上面的命令是我的git中最有用的命令生活节省了很多时间。
在将新提交的更改推送到远程服务器之前,请尝试使用git pull --rebase而不是git pull和手动merge,它将自动同步最新的远程服务器更改(通过获取+合并),并将本地最新提交位于git日志的顶部。无需担心手动拉/合并。
如果发生冲突,只需使用
git mergetool
git add conflict_file
git rebase --continue

在以下位置查找详细信息:http://gitolite.com/git-pull--rebase

#12 楼

简而言之,如果您知道其中一个存储库中的更改并不重要,并且想要解决所有更改以支持另一个存储库,请使用:

git checkout . --ours


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

git checkout . --theirs


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

否则您将必须使用GUI合并工具来一步一步地浏览文件,例如合并工具为p4merge,或写出您已经安装的任何人的名字。

git mergetool -t p4merge


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

评论


git checkout。 -他们解决了我的问题,谢谢

– Ramesh Chand
16 Mar 10 '16 at 6:53

如果您希望手动解决冲突,请尝试在Visual Studio Code中打开该文件夹,它会将文件标记为带有冲突的文件,并为每个文件中的冲突行添加颜色

–穆罕默德·塞利姆(Mohamed Selim)
16年7月3日在8:31



#13 楼

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


检查Git状态:获取补丁集:检出本地分支(在我的示例中为temp1):
git checkout -b temp1
从master提取最近的内容:
启动mergetool并检查冲突并修复它们...并使用当前分支检查远程分支中的更改:
git mergetool
再次检查状态:
git status
删除mergetool在本地创建的不需要的文件,通常mergetool会创建带有* .orig扩展名的多余文件。请删除该文件,因为它只是重复的文件,并在本地修复更改并添加文件的正确版本。
git add #your_changed_correct_files
再次检查状态:
git status
将更改提交到相同的提交ID(避免使用新的单独补丁集):
git commit --amend
推送到master分支:


#14 楼

共有3个步骤:



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

git status



检查文件,您会在其中找到标记为

<<<<<<<<head
blablabla




的冲突,将其更改为所需的方式,然后使用命令进行提交

git add solved_conflicts_files
git commit -m 'merge msg'




评论


为我工作!谢谢!

–努瓦贾亚瓦德纳
17年9月18日在4:00

在重新设置基准时,必须注意这一点。您应该使用git rebase --continue而不是git commit

–塞缪尔·道祖(Samuel Dauzon)
18-10-29在13:37

#15 楼

您可以采用其他方法详细描述的多种方式来解决合并冲突。

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

我个人习惯了两件事来避免这种情况。

而不是:

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


> or

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和clone有什么区别?

评论


嘿,我有点理解你的答案。但是由于我是github合并冲突的新手,所以我认为缺少一些东西。当您执行git checkout master和git fetch和git rebase --hard origin / master时,本地修改会如何?

– Suhaib
17年8月8日在17:43



我相信您应该添加有关操作的更多详细信息。您在回答中提到了另一个使我感到困惑的示例:我们执行git add。,它将保存我们的本地修改,以便我们可以跟进git checkout master吗?还是两种不同的情况?

– Suhaib
17年8月8日在17:47

@MichaelDurrant $ git rebase --hard origin / master b5a30cc159ba8dd错误:未知选项hard'用法:git rebase [-i] [options] [--exec ] [--onto ] [] []或:git rebase [-i] [选项] [--exec ] [--onto ] --root []或:git rebase --continue | -中止| --skip | --edit-do`

– Likejudo
5月23日20:23

#16 楼

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


#17 楼

如果要从分支(测试)合并到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:测试主机与主机之间没有冲突。您可以直接使用合并。

#18 楼

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

这将使您查看提交到文件中的内容他们分叉后的两个分支。通常,它更容易解决冲突。

#19 楼

使用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#项目中保留了重复的配置行。尽管它比我之前曾有过的“整个文件不同”更友好

–Mathijs Segers
17年9月8日在7:55

#20 楼

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

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

此博客文章进行了详细说明,但是基础是,通过UI“合并”两个分支后,您现在将看到一个“解决冲突”选项,该选项将带您进入允许您处理这些合并冲突的编辑器。



评论


这不是在问github,所以我投了反对票,我认为这是一个很差的答案。

–mschuett
17年1月25日在5:06

@mschuett是正确的,问题是“如何解决git中的冲突”,而不是“如何解决github中的冲突”。两者之间是有区别的,已经有太多人认为git和github是同一件事,所以任何传播这种感觉的人都是错误的。

–帕特里克·梅夫克(Patrick Mevzek)
18-4-5在16:21



#21 楼

我始终按照以下步骤来避免冲突。


git checkout master(进入master分支)
git pull(更新您的master以获得最新代码)
git checkout -b mybranch(签出一个新的分支并开始在该分支上工作,以便您的主服务器始终保持在主干顶部。)
git add。 AND git commit和git push(更改后在您的本地分支上)
git checkout master(回到您的master。)

现在您可以执行相同的操作并维护尽可能多的本地分支您想同时工作,只要有必要,我只需对您的分支进行git checkout。

#22 楼

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

运行git fetch然后git merge

运行git fetch然后git rebase

运行git pull时(实际上等于上述条件之一)
运行git stash pop

当您应用git补丁时(提交到导出文件的提交,例如通过电子邮件的提交)

您需要安装与Git兼容的合并工具来解决冲突。我个人使用KDiff3,发现它很方便。您可以在此处下载其Windows版本:
https://sourceforge.net/projects/kdiff3/files/
BTW如果安装Git Extensions,则其安装向导中可以选择安装Kdiff3。
然后设置git configs以将Kdiff用作其合并工具:
$ 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

(请记住用Kdiff exe文件的实际路径替换该路径。)
然后每次遇到合并时冲突,您只需要运行以下命令:
$ git mergetool

然后打开Kdiff3,然后首先尝试自动解决合并冲突。大多数冲突将自动解决,您需要手动修复其余的冲突。
这是Kdiff3的样子:

然后,完成操作后,保存文件,然后转到下一个有冲突的文件,然后您再次执行相同的操作,直到解决所有冲突为止。
要再次检查所有内容是否已成功合并,只需再次运行mergetool命令,您将得到以下结果:
$ git mergetool
No files need merging


#23 楼

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

TL; DR




Tpope提出了一个伟大的VIM插件fugitive。安装后,您可以运行:Gstatus来检查有冲突的文件,然后运行:Gdiff以3种方式合并以打开Git。

一旦进行三路合并,逃犯将使您可以按以下方式获取要合并的任何分支的更改:



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

:diffget //3,从合并分支获取更改:

完成文件合并后,在合并的文件中键入:Gwrite缓冲。
Vimcasts发布了一段精彩的视频,详细介绍了此步骤。

#24 楼

Gitlense for VS Code

您可以尝试Gitlense for VS Code,它们的主要功能是:

3。轻松解决冲突。

我已经喜欢此功能:



2。当前的线路异常。



3。天沟怪



4。状态栏谴责



有很多功能可以在这里查看。

#25 楼

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中找到您的承诺。
希望对这个问题有帮助的所有人。

#26 楼

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

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

#27 楼

对于正在使用Visual Studio的用户(在我的情况下为2015)


在VS中关闭项目。尤其是在大型项目中,使用UI进行合并时,VS往往会出现异常。

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

git checkout target_branch

git merge source_branch

然后在VS中打开项目并转到Team Explorer-> Branch。现在,出现一条消息,指出正在合并,并且在该消息的正下方列出了冲突的文件。
单击冲突的文件,您将可以选择合并,比较,获取源代码,获取目标。 VS中的合并工具非常易于使用。


评论


我在一个非常大的项目上使用VS Code 2017,因此无需关闭该项目。它处理得很好:)

–新世纪福音战士
17年8月10日在16:22

#28 楼

如果还没有的话,请尝试使用Visual Studio Code进行编辑。
它是在您尝试合并(并出现合并冲突)后执行的操作。VS代码会自动检测到合并冲突。

通过显示对原始副本所做的更改,它可以很好地帮助您,您是否应该接受incoming

current change(意味着合并前的原始副本)'?。

它对我有帮助,它也可以为您服务!

PS:仅当您在代码和Visual Studio Code中配置git时,它才有效。

#29 楼

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


#30 楼

如果您将intelliJ用作IDE
,请尝试通过

将父级合并到分支中
git checkout <localbranch>
git merge origin/<remotebranch>


它将显示所有这样的冲突


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


现在请注意,文件TestClass.java在intelliJ中以红色显示
也处于git状态将显示

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


在intelliJ中打开文件,它将具有带有

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


的节,其中HEAD是本地分支机构上的更改和origin /是远程分支机构上的更改。在这里保留您需要的东西,然后删除不需要的东西。那是

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