在 Git 合并冲突时,git checkout --oursgit checkout --theirs 用于选择保留哪一方的文件版本,特别适合处理自动生成的资源文件等不需要手动逐行解决的冲突。

基本用法

# 保留当前分支的版本(丢弃对方的修改)
git checkout --ours <file>

# 保留传入分支的版本(丢弃当前分支的修改)
git checkout --theirs <file>

# 解决冲突后需要 add
git add <file>

批量处理所有冲突文件:

git checkout --theirs .
git add .

场景实例

Engineer A、B 同时从 master checkout 自己的功能分支:

# Engineer A
git checkout -b feature-a

# Engineer B
git checkout -b feature-b

Engineer A 开发比较快先进行了 push:

git add .
git commit -m "feat: feature-a"
git checkout master
git merge feature-a
git push

Engineer B 在 push 前需要拉最新的 master,因为改到了同一行代码,出现代码冲突。以下两种方式 Engineer B 都在 feature-b 分支上操作:

merge 合并代码

在 feature-b 上将 master 合并进来:

git checkout feature-b
git fetch origin
git merge origin/master

在处理冲突的过程中:

# 以自己(Engineer B / feature-b)的代码为准
git checkout --ours .
git checkout --ours file.txt

# 以 master 上的代码为准(包含 Engineer A 的修改)
git checkout --theirs .

rebase 合并代码

在 feature-b 上将提交重放到 master 之上:

git checkout feature-b
git fetch origin
git rebase origin/master

在处理冲突的过程中,ours 和 theirs 语义与 merge 相反

# 以自己(Engineer B / feature-b)的代码为准
git checkout --theirs .

# 以 master 上的代码为准(包含 Engineer A 的修改)
git checkout --ours .

注意:rebase 时语义相反

mergerebase 中,--ours--theirs 的含义是反过来的:

操作--ours--theirs
git merge当前分支被合并的分支
git rebaserebase 的目标分支(upstream)你正在 rebase 的分支(你的提交)

这是因为 rebase 本质上是将你的提交逐个"重放"到目标分支上,此时 Git 视角下"当前分支"是目标分支。

References