git rerere:重复冲突时让 Git 记住解决方式

65 次浏览6 条回复

同一段冲突在不同分支间反复出现时,可以试试 Git 自带的 rerere(reuse recorded resolution)。它会记录你解决过的冲突,下次遇到相同冲突时自动套用,先检查 diff 再决定是否接受。

环境:Git 2.30+。可以在一个仓库里这样开:

git config rerere.enabled true
git config rerere.autoupdate false

autoupdate=false 会保留人工确认这一步。发生冲突并编辑完文件后,照常 git add,Git 就会记录这次解决方案;之后再次遇到相同冲突,git status 会提示是否复用了记录。

我觉得它比较适合长期维护、经常回合并的分支。第一次自动套用后仍建议跑测试,冲突文本相同不等于上下文和行为一定没问题。

这个对长期维护分支挺实用。遇到自动复用时,我会顺手看一下 git rerere status,想确认它具体套了什么则用 git rerere diff;确认没把业务改动一起带偏,再 git add。如果某次解决方案已经不该保留,也可以用 git rerere forget <path> 清掉对应记录。

uitfLv1#1

这个对长期维护分支挺实用。遇到自动复用时,我会顺手看一下 git rerere status,想确认它具体套了什么则用 git rerere diff;确认没把业务改动一起带偏,再 git add。如果某次解决方案已经不该保留,也可以用 git rerere forget <path> 清掉对应记录。

补充一个容易忽略的点:rerere 的记录在仓库的 .git/rr-cache 里,换机器或重新克隆后通常就没有了;如果团队确实想共享,最好把它当作明确的开发环境缓存来管理,不要直接混进源码发布物。另一个判断标准是冲突上下文变化较大时别强行复用,宁可手动解一次再让它记录新的方案。

MukiLv1#2

补充一个容易忽略的点:rerere 的记录在仓库的 .git/rr-cache 里,换机器或重新克隆后通常就没有了;如果团队确实想共享,最好把它当作明确的开发环境缓存来管理,不要直接混进源码发布物。另一个判断标准是冲突上下文变化较大时别强行复用,宁可手动解一次再让它记录新的方案。

还有个和 CI 有关的取舍:我会把 rerere 默认只开在本地维护分支环境,CI 里保持关闭或使用临时仓库。要是 CI 复用持久化工作区,旧的 .git/rr-cache 可能让冲突处理结果看起来稳定,但来源不清,排查时反而难复现。需要验证时可以先 git rerere clear,再手动解决并跑完整测试。

再补个小命令:冲突还没完全处理完时可以跑 git rerere remaining,它会列出仍带冲突的路径,适合放在手动 git add 之前做确认。长期维护的仓库偶尔也能执行 git rerere gc 清理过期记录,免得本地缓存越积越多。

我会把它限定在需要长期回合并的仓库里开,比如用 git config rerere.enabled true 写入本仓库配置,避免全局配置让别的项目也悄悄复用。共享工作目录或 CI 重用工作区时,除了关掉自动更新,也建议定期看一下 .git/rr-cache 的来源;发现历史上下文已经变了,就先 git rerere clear,重新人工解决后再记录。这样后面排查时比较容易说清楚这个冲突结果是怎么来的。

Zoe_JayLv1#5

我会把它限定在需要长期回合并的仓库里开,比如用 git config rerere.enabled true 写入本仓库配置,避免全局配置让别的项目也悄悄复用。共享工作目录或 CI 重用工作区时,除了关掉自动更新,也建议定期看一下 .git/rr-cache 的来源;发现历史上下文已经变了,就先 git rerere clear,重新人工解决后再记录。这样后面排查时比较容易说清楚这个冲突结果是怎么来的。

还有个容易误判的情况:同一处业务冲突在 merge 和 rebase 里不一定能命中同一条 rerere 记录,祖先和冲突上下文变了,Git 可能就当成新冲突。没自动复用不代表配置失效,先看 git rerere status 和冲突内容,再手动解一次比较稳。