TT Lab
开始
学习 学习路径 课程

Git 实战

同一个冲突,正在解第四遍

在 TT Lab 中继续学习

目标

在冲突标记中看到共同祖先,让 git 记住解决过一次的方案,并通过内容确认 -X ours 和 -s ours 会使结果文件有什么不同。

为什么重要

解决冲突靠的不是技术,而是判断。然而默认的冲突标记缺少判断所需的一项信息——原来是什么。不知道这一点,就无法区分“一方删除的”和“双方改成不同内容的”,选错的话,别人的修改就会悄悄消失。zdiff3 补上了这一栏。而在需要反复做出同一个判断的情形——不断 rebase 长期存在的分支,或定期把发布分支合回来——rerere 能让这个判断只做一次。最后两步要把名字相近、常被弄反的两个旋钮(knob)区分开来。如果出于想带入内容的目的使用 -s ours,历史中会写着已经合并,而代码里什么也没进来。

步骤

  1. 在 /root/gitx8/repo 创建若干分支,它们对同一行做了不同的修改。
  2. 把默认冲突标记和 zdiff3 标记并排保存到 notes/zdiff3.txt。
  3. 打开 rerere,解决一次冲突并完成合并。
  4. 撤销那次合并后再重新合并,把 git 自己应用了相同解决方案的情形保存到 notes/replay.txt。
  5. 用 -X ours 合并 sidefix,并把结果保存到 notes/xours.txt。
  6. 用 -s ours 合并 legacy,并把结果保存到 notes/sours.txt。
  7. 把两个旋钮的区别整理到 notes/strategies.txt。
  8. 在 notes/report.md 中总结减少重复冲突的方法。

参考

对同一行做了不同修改的分支

在 /root/gitx8/repo 创建若干分支,它们对同一行做了不同的修改。

把 handler.txt 写成从 a 到 g 的七行,在第一个提交处创建 topic、sidefix、legacy 三个分支。topic 和 main 对第二行做不同的修改,sidefix 修改第二行和第六行。第六行要离得远一些,这样在第 5 步才能看到不发生冲突的那部分改动。

显示原来是什么的那一栏

把默认冲突标记和 zdiff3 标记并排保存到 notes/zdiff3.txt。

先用 git merge topic 制造冲突,原样抄下 handler.txt,再 git merge --abort。然后用 git -c merge.conflictStyle=zdiff3 merge topic 再次制造同样的冲突,就会多出一栏。请补充一行说明那一栏是什么。

让它记录一次解决方案

打开 rerere,解决一次冲突并完成合并。

用 git config rerere.enabled true 打开,然后执行 git merge topic。把冲突的 handler.txt 第二行改成保留双方的 b by main and topic,git add 之后提交。请看提交时 git 说记录了什么,以及 .git/rr-cache 里生成了什么。

从第二次起,git 替你解决

撤销那次合并后再重新合并,把 git 自己应用了相同解决方案的情形保存到 notes/replay.txt。

用 git reset --hard HEAD~1 删掉合并提交,再次执行 git merge topic。输出中会多出一行,handler.txt 已经是解决后的状态。但查看 git status 仍然是 UU——因为它只应用,不暂存。请 git add 并提交来完成。

只在冲突的位置选我方的

用 -X ours 合并 sidefix,并把结果保存到 notes/xours.txt。

执行 git merge -X ours -m '<메시지>' sidefix(占位符为提交消息)。第二行发生了冲突,所以留下我方的;第六行没有冲突,所以 sidefix 的改动原样合入。sidefix-only.txt 也会进来。请原样抄下结果文件,并补充一行说明留下了什么、进来了什么。

只记下“已合并”,却什么也不带入

用 -s ours 合并 legacy,并把结果保存到 notes/sours.txt。

执行 git merge -s ours -m '<메시지>' legacy(占位符为提交消息)。结束后去找 legacy.txt,找不到。再看看 git diff --name-only HEAD^1 HEAD 是不是什么也没输出——这表示结果树与合并前一个字符也不差。然而 git merge-base --is-ancestor legacy main 为真。

名字相似的两个旋钮

把两个旋钮的区别整理到 notes/strategies.txt。

请用表格来写,四行就够了:它是什么(选项还是策略)、没有冲突的对方改动会怎样、对方新增的文件会怎样、什么时候使用。必须以第 5、6 步亲眼见到的文件名作为依据。

减少重复冲突的方法

在 notes/report.md 中总结减少重复冲突的方法。

请写明:两行配置(rerere.enabled、merge.conflictStyle)为什么值得默认打开,rerere 记住什么、不记住什么,如何删除解错的方案,以及一开始就少制造冲突的习惯。