如何解决 Git 存储库中的合并冲突?
尝试:
git mergetool
它会打开一个 GUI,引导您完成每个冲突,您可以选择如何合并。有时它需要在之后进行一些手工编辑,但通常它本身就足够了。这肯定比手动完成整个事情要好得多。
[此命令] 不一定会打开 GUI,除非您安装一个。为我运行 git mergetool 导致使用 vimdiff。您可以安装以下工具之一来使用它:meld、opendiff、kdiff3、tkdiff、xxdiff、tortoisemerge、gvimdiff、diffuse、ecmerge、p4merge、araxis、vimdiff、emerge。
以下是基于 this link 使用 vimdiff
解决合并冲突的示例过程。
第 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 导航的更多信息是 here 和 here。
第 4 步。您可以通过以下方式编辑 MERGED 视图
如果您想从 REMOTE 获取更改
:diffg RE
如果您想从 BASE 获取更改
:diffg BA
如果您想从 LOCAL 获取更改
:diffg LO
第 5 步:保存、退出、提交和清理
:wqa
保存并退出 vi
git commit -m "message"
git clean
删除差异工具创建的额外文件(例如 *.orig)。
这是一个可能的用例,从顶部开始:
您将进行一些更改,但是糟糕,您不是最新的:
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.
达达!
git merge --help
this question
我发现合并工具很少能帮助我理解冲突或解决方案。我通常更成功地在文本编辑器中查看冲突标记并使用 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.
>>>>>>>
中间部分是共同祖先的样子。这很有用,因为您可以将其与顶部和底部版本进行比较,以更好地了解每个分支上的更改内容,从而更好地了解每个更改的目的。
如果冲突只有几行,这通常会使冲突非常明显。 (知道如何解决冲突是非常不同的;你需要知道其他人在做什么。如果你感到困惑,最好把那个人叫到你的房间,这样他们就可以看到你在看什么在。)
如果冲突时间较长,那么我会将三个部分分别剪切并粘贴到三个单独的文件中,例如“mine”、“common”和“theirs”。
然后我可以运行以下命令来查看导致冲突的两个差异块:
diff common mine
diff common theirs
这与使用合并工具不同,因为合并工具也会包含所有不冲突的差异数据块。我觉得这让人分心。
提示二
已经有人提到了这一点,但是了解每个 diff hunk 背后的意图通常对于了解冲突的来源以及如何处理它非常有帮助。
git log --merge -p <name of file>
这显示了在共同祖先和您要合并的两个头之间触及该文件的所有提交。 (因此它不包括合并之前两个分支中已经存在的提交。)这可以帮助您忽略明显不是当前冲突因素的差异大块。
提示三
使用自动化工具验证您的更改。
如果您有自动化测试,请运行它们。如果您有 lint,请运行它。如果它是一个可构建的项目,则在提交之前构建它,等等。在所有情况下,您都需要进行一些测试以确保您的更改不会破坏任何东西。 (哎呀,即使没有冲突的合并也会破坏工作代码。)
提示四
未雨绸缪;与同事沟通。
提前计划并了解其他人正在做什么可以帮助防止合并冲突和/或帮助更早地解决它们 - 而细节仍然是新鲜的。
例如,如果您知道您和另一个人都在进行不同的重构,这些重构都会影响同一组文件,那么您应该提前互相交谈,并更好地了解你们每个人的更改类型制造。如果您按顺序而不是并行进行计划更改,您可能会节省大量时间和精力。
对于跨越大量代码的重大重构,您应该强烈考虑按顺序工作:每个人都停止在代码的那个区域工作,而一个人执行完整的重构。
如果您不能连续工作(可能是由于时间压力),那么就预期的合并冲突进行沟通至少可以帮助您在细节仍然记忆犹新的情况下更快地解决问题。例如,如果一个同事在一周内进行了一系列破坏性的提交,您可以选择在该周内每天一次或两次在该同事分支上合并/rebase。这样,如果你确实发现了合并/变基冲突,你可以更快地解决它们,而不是等待几周将所有内容合并到一个大块中。
提示五
如果您不确定合并,请不要强行合并。
合并可能会让人感到不知所措,尤其是当有很多冲突文件并且冲突标记覆盖数百行时。通常在估算软件项目时,我们没有足够的时间来处理诸如处理复杂合并之类的开销项目,因此花几个小时剖析每个冲突感觉真的很累。
从长远来看,提前计划并了解其他人正在做什么是预测合并冲突并准备在更短的时间内正确解决它们的最佳工具。
p4merge
,它可以与 Perforce 的其他工具分开安装和使用(我没有使用过,但听说过抱怨)。
git config merge.conflictstyle diff3
- 谢谢您,先生。这是惊人的,并让我从试图找到(并支付 $$)一个好的 3 路合并 GUI 中解脱出来。 IMO这更好,因为它显示了共同的祖先以及本地/远程,和显示了(AFAIK)没有GUI的最后提交日志行。提交绝对可以帮助您确定哪些代码属于哪个分支。
diff3
。默认的冲突风格使得一些冲突实际上无法解决。有关详细信息,请参阅 stackoverflow.com/questions/27417656/…
确定哪些文件存在冲突(Git 应该告诉你这一点)。打开每个文件并检查差异; Git 对它们进行了划分。希望保留每个块的哪个版本是显而易见的。您可能需要与提交代码的其他开发人员讨论它。一旦你解决了文件中的冲突 git add the_file.解决所有冲突后,请执行 git rebase --continue 或 Git 在您完成时要求执行的任何命令。
git add
在索引中暂存文件;它确实不向存储库添加任何内容。 git commit
将内容添加到存储库。这种用法对合并有意义——合并会自动暂存所有可以自动合并的更改;完成后,您有责任合并其余更改并将其添加到索引中。
当同时对文件进行更改时,会发生合并冲突。以下是如何解决它。
命令行界面
以下是当您进入冲突状态时要执行的简单步骤:
请注意冲突文件列表: git status (在未合并路径部分下)。通过以下方法之一分别解决每个文件的冲突: 使用 GUI 解决冲突:git mergetool(最简单的方法)。要接受远程/其他版本,请使用:git checkout --theirs path/file。这将拒绝您对该文件所做的任何本地更改。要接受本地/我们的版本,请使用: git checkout --ours path/file 但是你必须小心,因为远程更改是由于某种原因而发生的冲突。相关:git中“我们的”和“他们的”的确切含义是什么?手动编辑冲突文件并在 <<<<>>>>>> 之间查找代码块,然后从上面或下面选择版本 =====。请参阅:如何呈现冲突。路径和文件名冲突可以通过 git add/git rm 解决。最后,使用以下命令查看准备提交的文件:git status。如果您在未合并的路径下仍有任何文件,并且您确实手动解决了冲突,那么让 Git 知道您通过以下方式解决了它:git add path/file。如果所有冲突都已成功解决,请通过以下方式提交更改: git commit -a 并像往常一样推送到远程。
另请参阅:GitHub 上的 Resolving a merge conflict from the command line
如需实用教程,请查看:Scenario 5 - Fixing Merge Conflicts by Katacoda。
差异合并
我已成功使用 DiffMerge,它可以在 Windows、macOS 和 Linux/Unix 上直观地比较和合并文件。
它可以以图形方式显示 3 个文件之间的更改,并允许自动合并(在安全的情况下)和对编辑结果文件的完全控制。
https://i.stack.imgur.com/tAURE.png
图片来源:DiffMerge(Linux 截图)
只需下载它并在 repo 中运行:
git mergetool -t diffmerge .
苹果系统
在 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 工具的一部分),它允许您将两个文件或目录合并在一起以创建第三个文件或目录。
查看 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 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
都会更新索引,您的差异将不再显示它。当所有冲突都得到处理并且它们的文件已经被 git add
编辑后,git commit
将完成您的合并。
我要么想要我的或他们的完整版本,要么想要查看个别更改并为每个更改做出决定。
完全接受我或他们的版本:
接受我的版本(本地,我们的):
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 <文件名> git commit -m "merged bla bla"
默认 mergetool
在命令行中工作。如何使用命令行合并工具应该是一个单独的问题。
您也可以为此安装 visual tool,例如 meld
并运行
git mergetool -t meld
它将打开本地版本(我们的)、“基础”或“合并”版本(合并的当前结果)和远程版本(他们的)。完成后保存合并后的版本,再次运行 git mergetool -t meld
直到出现“没有文件需要合并”,然后转到步骤 3 和 4。
请参阅 How Conflicts Are Presented 或 Git 中的 git merge
文档以了解什么是合并冲突标记。
此外,How to Resolve Conflicts 部分解释了如何解决冲突:
看到冲突后,您可以做两件事: 决定不合并。您需要的唯一清理是将索引文件重置为 HEAD 提交以反转 2. 并清理 2. 和 3. 所做的工作树更改; git merge --abort 可用于此。解决冲突。 Git 将标记工作树中的冲突。将文件编辑成形状并将它们添加到索引中。使用 git commit 来达成交易。您可以使用多种工具来解决冲突: 使用合并工具。 git mergetool 启动一个图形化的合并工具,它将帮助你完成合并。看看差异。 git diff 将显示三向差异,突出显示 HEAD 和 MERGE_HEAD 版本的更改。查看每个分支的差异。 git log --merge -p
您还可以在Pro Git书籍部分Basic Merge Conflicts中了解合并冲突标记以及如何解决它们。
对于想要半手动解决合并冲突的 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 pull --rebase
上面这个命令是我 Git 生活中最有用的命令,它节省了很多时间。
在将您新提交的更改推送到远程服务器之前,请尝试 git pull --rebase
而不是 git pull
和手动 merge
,它会自动同步最新的远程服务器更改(使用 fetch + merge)并将您的本地最新提交放在顶部在 Git 日志中。无需担心手动拉/合并。
如果发生冲突,只需使用
git mergetool
git add conflict_file
git rebase --continue
在以下位置查找详细信息:What does “git pull –rebase” do?
简单地说,如果您很清楚其中一个存储库中的更改并不重要,并且想要解决所有更改以支持另一个存储库,请使用:
git checkout . --ours
解决有利于您的存储库的更改,或
git checkout . --theirs
解决有利于其他或主存储库的更改。
否则您将不得不使用 GUI 合并工具逐个浏览文件,例如合并工具是 p4merge
,或者写下您已经安装的任何人的名字
git mergetool -t p4merge
完成一个文件后,您必须保存并关闭,以便打开下一个文件。
分为三个步骤:
通过命令 git status 查找哪些文件导致冲突检查文件,您会在其中找到标记为 <<<<<<
请按照以下步骤修复 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 存储库)
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
正如其他人所详述的那样,您可以通过多种方式修复合并冲突。
我认为真正的关键是了解本地和远程存储库的变化是如何流动的。关键是理解跟踪分支。我发现我认为跟踪分支是我的本地、实际文件目录和定义为源的远程目录之间的“中间缺失的部分”。
我个人已经养成了两件事来帮助避免这种情况的习惯。
代替:
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?
git checkout master
和 git fetch
和 git rebase --hard origin/master
时,您的本地修改会发生什么
git add .
,它会保存我们的本地修改以便我们可以跟进 git checkout master
吗?或者他们是两个不同的场景?
$ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option
hard' 用法: git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] 或: git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>] 或: git rebase --continue | --中止 | --跳过 | --edit-todo `
如果您想从分支 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
第7步:然后test和master之间就没有冲突了。您可以直接使用合并。
使用耐心
对于大的合并冲突,使用 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>
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
(在这种情况下您要合并到的分支)。
这将允许您查看两个分支在分歧后进入文件的提交。它通常使解决冲突变得容易得多。
截至 2016 年 12 月 12 日,您可以在 github.com 上合并分支并解决冲突
因此,如果您不想使用旧答案中提供的命令行或任何第 3 方工具,请使用 GitHub 的本机工具。
This blog post 详细解释,但基本情况是,通过 UI '合并'两个分支后,您现在将看到一个“解决冲突”选项,该选项将带您进入允许您处理这些合并冲突的编辑器。
https://i.stack.imgur.com/1YX5P.gif
合并冲突可能发生在不同的情况下:
运行 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 的样子:
https://i.stack.imgur.com/Xw3nw.png
然后一旦你完成,保存文件,它会转到下一个有冲突的文件,你再次做同样的事情,直到所有的冲突都得到解决。
要检查所有内容是否合并成功,只需再次运行 mergetool 命令。你应该得到这个结果:
$ git mergetool
No files need merging
我总是按照以下步骤来避免冲突。
git checkout master(来到master分支)
git pull (更新你的主人以获得最新的代码)
git checkout -b mybranch (签出一个新的分支并开始在该分支上工作,以便您的主干始终保持在主干的顶部。)
混帐添加。和 git commit 和 git push (在您更改后的本地分支上)
git checkout master(回到你的主人那里)
现在,您可以通过在必要时对您的分支执行 git checkout
来执行相同的操作并维护所需的多个本地分支并同时工作。
适用于 Visual Studio 代码的 GitLens
您可以为 Visual Studio Code 尝试 GitLens。主要特点是:
3. 轻松解决冲突
我已经喜欢这个功能了:
https://i.stack.imgur.com/4YBdY.png
2. 当前线责。
https://i.stack.imgur.com/LuqoC.png
3. 天沟责备
https://i.stack.imgur.com/giS9K.png
4.状态栏责备
https://i.stack.imgur.com/ZO7pm.png
并且有很多特点。您可以检查它们here。
我明白什么是合并冲突,但是当我看到 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
但是 here 帮助了我:
<<<<<<< 和 ======= 之间的所有内容都是一个文件中的内容,并且
======= 和 >>>>>> 之间的所有内容都是另一个文件中的内容
因此,从字面上看,您所要做的就是打开具有合并冲突的文件,然后从任一分支中删除这些行(或者只是使它们相同),合并将立即成功。问题解决了!
这个答案是为像我这样喜欢在编辑器中做所有事情的 Vim 用户添加一个替代方案。
TL;博士
https://i.stack.imgur.com/iW2iC.gif
Tpope 为 Vim 开发了这个很棒的插件,名为 fugitive。安装后,您可以运行 :Gstatus
检查有冲突的文件,运行 :Gdiff
以三向合并打开 Git。
一旦进入三路合并,fugitive 将让您以下列方式获取您正在合并的任何分支的更改:
:diffget //2,从原始(HEAD)分支获取更改:
:diffget //3,从合并分支获取更改:
完成文件合并后,在合并的缓冲区中键入 :Gwrite
。
Vimcasts 发布了a great video,详细解释了这些步骤。
我正在使用 Microsoft 的 Visual Studio Code 来解决冲突。使用起来非常简单。我在工作区中保持我的项目打开。它检测并突出显示冲突。此外,它提供了 GUI 选项来选择我想从 HEAD 保留或传入的任何更改。
https://i.stack.imgur.com/RXgnQ.png
对于那些使用 Visual Studio 的人(在我的例子中是 Visual Studio 2015)
在 Visual Studio 中关闭您的项目。尤其是在大型项目中,Visual Studio 在使用 UI 进行合并时往往会崩溃。在命令提示符下进行合并。 git checkout target_branch git merge source_branch 然后在 Visual Studio 中打开项目并转到 Team Explorer → Branch。现在有一条消息显示 Merge is pending 并且冲突文件列在消息下方。单击冲突文件,您将可以选择合并、比较、获取源和获取目标。 Visual Studio 中的合并工具非常易于使用。
如果您使用 IntelliJ IDEA 作为 IDE,请尝试通过以下方式将父级合并到您的分支:
git checkout <localbranch>
git merge origin/<remotebranch>
它将显示所有冲突,如下所示:
A_MBPro:test anu$ git merge origin/ Auto-merging src/test/java/com/.../TestClass.java CONFLICT (content): Merge conflict in 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
git mergetool -y
来节省一些击键。git mergetool
导致使用了vimdiff
。您可以安装以下工具之一来使用它:meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge
。git mergetool -t bc3
)。