同一组分支反复合并或变基时,相似冲突可能需要多次做出相同修改。Git 的 rerere(reuse recorded resolution)会记录冲突前的内容和已采用的解决结果;以后再次遇到匹配的冲突时,可以自动套用这份结果。
环境:Git 2.39+;Linux 或 macOS;Bash;需要 mktemp。下面只操作新建的临时仓库。
root=$(mktemp -d)
trap 'rm -rf -- "$root"' EXIT
repo="$root/demo"
git init -b main "$repo"
git -C "$repo" config user.name "Rerere Demo"
git -C "$repo" config user.email "[email protected]"
git -C "$repo" config rerere.enabled true
git -C "$repo" config rerere.autoupdate true
printf 'mode=base\n' >"$repo/app.conf"
git -C "$repo" add app.conf
git -C "$repo" commit -m base
git -C "$repo" switch -c feature
printf 'mode=feature\n' >"$repo/app.conf"
git -C "$repo" commit -am feature
git -C "$repo" switch main
printf 'mode=main\n' >"$repo/app.conf"
git -C "$repo" commit -am main
# 第一次合并产生预期冲突。
if git -C "$repo" merge feature; then
printf 'expected a conflict\n' >&2
exit 1
fi
printf 'mode=combined\n' >"$repo/app.conf"
git -C "$repo" add app.conf
git -C "$repo" commit -m 'record resolution'
# 回到合并前,再制造同一冲突。
git -C "$repo" reset --hard HEAD^
if git -C "$repo" merge feature; then
printf 'expected a conflict\n' >&2
exit 1
fi
git -C "$repo" status --short
git -C "$repo" diff --cached -- app.conf
第二次 merge 仍会以非零状态报告冲突,但 rerere.autoupdate=true 会把先前的 mode=combined 解决结果写回并加入暂存区;git status --short 会把 app.conf 显示为已暂存修改。记录保存在当前仓库的 .git/rr-cache,不会修改其他仓库。
自动复用不等于自动判定语义正确。提交前应检查 git diff --cached 并运行项目测试;上下文变化较大时,Git 也可能无法匹配旧记录。若只希望写回工作区、不希望自动暂存,可以保持 rerere.enabled=true,同时不启用 rerere.autoupdate。