如何解决Git仓库中的合并冲突

如何解决Git仓库中的合并冲突

技术背景

在多人协作的软件开发项目中,使用Git进行版本控制时,不同开发者可能会同时对同一文件的相同部分进行修改。当尝试合并这些修改时,就会产生合并冲突。合并冲突需要手动解决,否则无法完成合并操作。

实现步骤

1. 识别冲突文件

使用git status命令查看处于冲突状态的文件,这些文件会显示在Unmerged paths部分。

1
git status

2. 解决冲突

可以采用以下几种方式解决冲突:

  • 使用图形化工具:运行git mergetool命令,它会打开一个图形界面,引导你处理每个冲突。不过,需要安装相应的图形化工具,如meldopendiffkdiff3等。
1
git mergetool
  • 接受远程/其他版本:使用git checkout --theirs path/file命令接受远程版本,这会丢弃本地对该文件所做的修改。
1
git checkout --theirs path/file
  • 接受本地/我们的版本:使用git checkout --ours path/file命令接受本地版本。但要注意,远程冲突更改可能是有原因的。
1
git checkout --ours path/file
  • 手动编辑冲突文件:打开冲突文件,查找<<<<<<<>>>>>>>之间的代码块,在=====上下选择合适的版本。
  • 解决路径和文件名冲突:使用git addgit rm命令。

3. 审查并提交更改

使用git status命令审查准备提交的文件。如果手动解决冲突后,仍有文件处于Unmerged paths状态,使用git add path/file命令告知Git冲突已解决。

1
2
git status
git add path/file

当所有冲突都解决后,使用git commit -a命令提交更改,并像往常一样推送到远程仓库。

1
2
git commit -a
git push

核心代码

设置vimdiff为默认合并工具

1
2
3
git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

使用vimdiff解决冲突

1
git mergetool

在vimdiff中获取不同版本的更改

1
2
3
4
5
6
# 获取REMOTE版本的更改
:diffg RE
# 获取BASE版本的更改
:diffg BA
# 获取LOCAL版本的更改
:diffg LO

保存、退出、提交和清理

1
2
3
:wqa  # 保存并退出vi
git commit -m "message"
git clean # 移除额外文件(如 *.orig)

最佳实践

采用diff3合并冲突样式

使用git config merge.conflictstyle diff3命令,该样式会生成包含共同祖先版本的冲突标记,有助于更好地理解每个分支的更改。

1
git config merge.conflictstyle diff3

理解每个diff块的意图

使用git log --merge -p <name of file>命令查看在共同祖先和要合并的两个分支头之间对该文件进行的所有提交,忽略与当前冲突无关的diff块。

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

用自动化工具验证更改

在提交之前,运行自动化测试、代码检查工具,或者构建项目,确保更改没有破坏任何功能。

提前规划并与同事沟通

提前规划并了解他人的工作内容,有助于避免合并冲突或在细节仍清晰时尽早解决冲突。对于大型重构,可考虑串行工作。

不确定时不要强制合并

合并可能会让人感到压力,尤其是在有大量冲突文件时。提前规划和了解他人的工作是预测和解决合并冲突的最佳方法。

常见问题

git mergetool未打开图形界面

git mergetool不一定会打开图形界面,除非安装了相应的图形化工具。可以安装meldopendiff等工具,并使用git config merge.tool "your.tool"命令设置所选工具。

1
git config merge.tool "meld"

git log --merge -p显示过多提交

git log --merge -p显示的提交过多时,可以使用以下命令分别查看两个分支的提交:

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

其中,$MERGED_IN_BRANCH是要合并的分支,[path]是冲突文件的路径。


如何解决Git仓库中的合并冲突
https://119291.xyz/posts/2025-05-08.how-to-resolve-merge-conflicts-in-git-repository/
作者
ww
发布于
2025年5月8日
许可协议