在 Git 合并冲突时,git checkout --ours 和 git 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 时语义相反
在 merge 和 rebase 中,--ours 和 --theirs 的含义是反过来的:
| 操作 | --ours | --theirs |
|---|---|---|
git merge | 当前分支 | 被合并的分支 |
git rebase | rebase 的目标分支(upstream) | 你正在 rebase 的分支(你的提交) |
这是因为 rebase 本质上是将你的提交逐个"重放"到目标分支上,此时 Git 视角下"当前分支"是目标分支。