使用 Git 的 rerere 功能摆脱重复冲突的困扰
Using Git's rerere feature to escape recurring conflict hell

原始链接: https://gist.github.com/skipcloud/f1033afb4fa5681d69fa63458cc95928

如果您经常为重复出现的合并冲突感到头疼,Git 的 `rerere`(Reuse Recorded Resolution,重用记录的解决方案)功能就是解决之道。它能让 Git “记住”您之前是如何解决特定冲突的,并在将来合并或变基时再次出现同样冲突时,自动应用相同的修复。 要全局启用此功能,请运行: `git config --global rerere.enabled true` 启用后,每当您遇到冲突,Git 都会记录“预镜像”(初始冲突状态)以及您的手动解决方法。如果您必须重新合并,或者将来再次出现相同的冲突,Git 将识别出该模式,通知您“已使用之前的解决方案解决 [文件]”,并自动应用您的修复。这将大幅减少多次重复解决相同合并冲突的繁琐工作。

Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 使用 Git 的 rerere 功能摆脱循环冲突地狱 (gist.github.com) 9 点,由 ankitg12 发布于 4 小时前 | 隐藏 | 过往 | 收藏 | 讨论 | 帮助 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

Have you ever tried to merge two branches only to end up in conflict hell? You fix a bunch of conflicts only to run git merge --continue and be presented with the same conflicts. Repeat this process and after a few iterations you give up because it just isn't worth the pain and effort.

Would you be surprised to know that there is a git feature specifically for this problem? It's called rerere and I'm going to enrich your life with it now. (I'm going to talk specifically about merging but I think it also helps rebasing)

rerere stands for Reuse Recorded Resolution. The TL;DR version is you ask git to remember how you've resolved hunks in the past, and if the same one comes up for a file in future just redo what you did last time.

To enable this feature just run this lovely command git config --global rerere.enabled true. You can also turn it on by creating this directory in your projects .git/rr-cache, although the global setting is much clearer.

I'll try to take you through an example of how this works, bear with me it might get long.

We have our (tiny) project with only one file in it, which looks like this

.
└── user.rb

0 directories, 1 file

I branch off master to create a branch called dev and I add a line to user.rb. Now I would like to stage this change so I pull down staging and try to merge my dev branch but uh oh, someone has merged a change to staging affecting the same line in user.rb that I am editing.

/tmp/example [staging] » git merge dev
Auto-merging user.rb
CONFLICT (content): Merge conflict in user.rb
Automatic merge failed; fix conflicts and then commit the result.

We've all seen this before, a run of the mill conflict message. However if you were to have rerere enabled you would get this output

/tmp/example [staging] » git merge dev
Auto-merging user.rb
CONFLICT (content): Merge conflict in user.rb
Recorded preimage for 'user.rb'
Automatic merge failed; fix conflicts and then commit the result.

You can now see a new line saying Recorded preimage for 'user.rb'. Running git rerere diff right now will give you the current state of the resolution file:

/tmp/example [c013552] » git rerere diff
--- a/user.rb
+++ b/user.rb
@@ -1,5 +1,5 @@
-<<<<<<<
-hello
-=======
+<<<<<<< HEAD
 hi
 ->>>>>>>
 +=======
 +hello
 +>>>>>>> commit from dev

You go about the usual conflict workflow, choose which changes to keep, and commit the result. If you run git rerere diff again, you see the recorded resolution:

/tmp/example [c013552] » git rerere diff
--- a/user.rb
+++ b/user.rb
@@ -1,5 +1 @@
-<<<<<<<
 hello
-=======
-hi
->>>>>>>

Running git merge --continue will apply your commit and tell you about the new resolution for our file:

/tmp/example [c013552] » git merge --continue
Recorded resolution for 'user.rb'.```
Let's undo that merge with `git reset --hard HEAD^` and merge again:

```/tmp/example [staging] » git merge dev
Auto-merging user.rb
CONFLICT (content): Merge conflict in user.rb
Resolved 'user.rb' using previous resolution.
Automatic merge failed; fix conflicts and then commit the result.
/tmp/example [staging] » git add .
/tmp/example [staging] » git merge --continue
[staging f4a7d36] Merge branch 'dev' into staging

The important line in this output is Resolved 'user.rb' using previous resolution.. I didn't need to even look at the file, just commit the result. This worked because git saw the conflict, looked in the rr-cache folder and recognised this hunk from this file from a previous merge and applied your decision from last time!

As always, I hope you found that useful.

联系我们 contact @ memedata.com