在拉取时以对方更改解决 Git 合并冲突

在拉取时以对方更改解决 Git 合并冲突

技术背景

在使用 Git 进行版本控制时,多人协作开发或在不同分支间进行合并操作时,经常会遇到合并冲突的问题。合并冲突是指当两个或多个分支对同一文件的同一部分进行了不同的修改,Git 无法自动确定如何合并这些更改,就需要开发者手动解决冲突。本文将介绍如何在拉取时以对方的更改来解决合并冲突。

实现步骤

拉取时使用指定策略

可以使用以下命令在拉取时以对方的更改解决冲突:

1
git pull -s recursive -X theirs <remoterepo or other repo>

对于默认仓库,可简化为:

1
git pull -X theirs

已处于冲突状态

  • 接受所有对方更改
1
2
git checkout --theirs .
git add .
  • 接受所有己方更改
1
2
git checkout --ours .
git add .

处理单个冲突文件

  • 接受对方更改
1
2
git checkout --theirs path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php
  • 接受己方更改
1
2
git checkout --ours path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php

取消合并并重新拉取

如果已经处于冲突状态,且不想逐个检查路径,可以尝试:

1
2
git merge --abort
git pull -X theirs

忽略本地修改

如果想简单地忽略仓库中文件的任何本地修改,例如在一个应始终是远程仓库镜像的客户端上,可以运行:

1
git fetch && git reset --hard origin/master

使用合并策略选项

  • 接受所有当前更改并忽略任何传入更改
1
git merge [branch] --strategy-option ours
  • 覆盖任何当前更改并接受所有传入冲突更改
1
git merge [branch] --strategy-option theirs

解决特定分支的所有冲突

1
git diff --name-only --diff-filter=U | xargs git checkout ${branchName}

例如,在合并状态下,想保留冲突文件的 master 版本:

1
git diff --name-only --diff-filter=U | xargs git checkout master

VS Code 集成 Git IDE

  • Ctrl + Shift + P 打开命令面板。
  • 选择 Merge Conflict: Accept All Incoming 接受冲突文件中的所有传入更改。

自定义合并工具

可以在 git-config 中配置自定义合并工具,例如:

1
2
[mergetool "ours"]
cmd = "sed -i -e '/^<<<<<<</d' -e '/^=======/,/^>>>>>>>/d' -- $MERGED"

然后使用 git mergetool --tool=ours 调用。

Emacs smerge - mode

在 Emacs 中使用 smerge - mode 定义函数来解决所有冲突标记:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defun aj/smerge-keep-mine-all ()
""
(interactive)
(save-excursion
(beginning-of-buffer)
(while (ignore-errors 'user-error (progn (smerge-next) t))
(smerge-keep-mine))))

(defun aj/smerge-keep-other-all ()
""
(interactive)
(save-excursion
(beginning-of-buffer)
(while (ignore-errors 'user-error (progn (smerge-next) t))
(smerge-keep-other))))

Visual Studio 2022

  1. 进入“Manage Branches”,双击要将 dev 合并到的分支。
  2. 右键点击 dev,选择 Merge 'dev' into 'your - branch'
  3. 若出现大量合并冲突,点击 Abort
  4. 打开 cmd
  5. 输入 git merge --strategy-option ours --no - commit dev 并回车。
  6. 回到 Visual Studio,输入提交信息并提交。

合并单个文件

master 分支合并到 development 分支,并接受 master 分支中单个特定文件的版本:

1
2
3
4
5
6
git pull origin master
git checkout --theirs path/to/foo
git add path/to/foo
git commit -a -m "Merge master into development branch"
git pull
git push

核心代码

使用 sed 解决冲突

  • 使用对方更改解决冲突
1
sed -i -e '/^<<<<<<</,/^=======/d' -e '/^>>>>>>>/d' foo
  • 使用己方更改解决冲突
1
sed -i -e '/^<<<<<<</d' -e '/^=======/,/^>>>>>>>/d' foo

最佳实践

  • 在进行合并操作前,先确保本地仓库是最新的,可以使用 git pull 拉取最新代码。
  • 对于重要的项目,建议在测试环境中先进行合并操作,确认没有问题后再推送到生产环境。
  • 如果不确定要接受哪些更改,可以先使用 git diff 查看具体的差异,再做决定。

常见问题

出现 fatal: Not possible to fast - forward, aborting. 错误

可以使用以下命令拉取并接受对方更改,同时进行快进合并:

1
git pull -X theirs --ff

git checkout --ours/theirs 无法解决冲突

可以尝试使用 git checkout HEAD -- path/to/filegit checkout MERGE_HEAD -- path/to/file,然后执行 git add .


在拉取时以对方更改解决 Git 合并冲突
https://119291.xyz/posts/resolve-git-merge-conflicts-in-favor-of-their-changes-during-a-pull/
作者
ww
发布于
2025年5月22日
许可协议