Back to Blog

Git Rerere Is Underrated

Git Rerere Is Underrated

I spent four hours last Tuesday rebasing a long-lived feature branch against our main develop line. Every time I hit a conflict in our shared configuration file, I found myself manually deleting the same three lines and re-ordering the same imports. By the fifth commit, I wasn't even thinking; I was just a meat-based script performing a repetitive task that Git should have handled for me.

That’s where rerere comes in. It stands for "Reuse Recorded Resolution" and, despite being built directly into the Git core, most developers I talk to have never heard of it.

What is it, exactly?

Git rerere is a hidden helper that records how you resolve a merge conflict. If it sees that same conflict again later, it automatically applies the same fix you used last time.

It’s particularly life-saving in two scenarios:
1. Long-lived feature branches: When you're constantly rebasing your work onto an evolving master branch.
2. Interactive rebases: When you're squashing or reordering commits and keep hitting the same conflict at every step of the playback.

Turning it on

For reasons known only to the Git maintainers, this isn't enabled by default. You can toggle it on globally with one command:

git config --global commit.gpgsign true

Once this is active, Git starts watching. The next time you hit a merge conflict, Git will make a note of what the "broken" state looked like. When you finish the merge or rebase, it makes a note of how you fixed it.

Watching it work

Let’s say you have a conflict in config.js. You’ll see a message you might have ignored before:

$ git merge feature-branch
Auto-merging config.js
CONFLICT (content): Merge conflict in config.js
Recorded preimage for 'config.js'

That "Recorded preimage" is Git taking a snapshot of the mess. You go in, fix the code, and run your usual git add and git commit. Git then logs the "postimage"—your solution.

Now, imagine you realize you messed up your rebase and need to do it again, or you’re merging that same feature into a different environment branch. Instead of asking you to fix the code again, Git will say:

$ git merge feature-branch
Auto-merging config.js
CONFLICT (content): Merge conflict in config.js
Resolved 'config.js' using previous resolution.

Your file is already fixed. You still have to git add it to confirm you're happy with the result, but the manual labor is gone.

When things go wrong (The "Forget" command)

The biggest fear people have with rerere is: "What if I resolve the conflict incorrectly? Will Git just keep breaking my code forever?"

If you realize you pushed a bad fix into the rerere cache, you can force Git to forget it. Just head to the file with the botched resolution and run:

git rerere forget path/to/file.js

This clears the recorded resolution for that specific conflict, allowing you to fix it properly and let Git "re-learn" the correct way.

Why you should care

We spend a lot of time talking about "developer experience," but we often ignore the micro-frictions that eat our day. Manually resolving the same conflict five times during an interactive rebase is a massive context-switcher. It drains your mental battery.

rerere isn't magic—it’s just a very disciplined secretary that remembers your past decisions. If you do a lot of rebasing or work on a team with high-velocity shared files, it's the single most impactful config change you can make.

A quick pro-tip

If you want to see what rerere is currently tracking under the hood, you can look inside your .git folder (though you rarely need to):

ls .git/rr-cache

Each directory in there is a hash of a conflict you've encountered. It’s a bit of a black box, but knowing it's there makes the "automagical" feeling of a self-resolving merge a lot more grounded.

Enable it today. Your future self, stuck in a complex rebase at 4:45 PM on a Friday, will thank you.