131

I've read various things about git's rerere feature, and I'm considering enabling it.

The git rerere functionality is a bit of a hidden feature. The name stands for “reuse recorded resolution” and, as the name implies, it allows you to ask Git to remember how you’ve resolved a hunk conflict so that the next time it sees the same conflict, Git can resolve it for you automatically.

https://git-scm.com/book/en/v2/Git-Tools-Rerere

But I haven't seen anyone mention any possible problems that could arise while using rerere.

I have to assume there is a downside, or it would probably be enabled by default. So is there any downside to enabling rerere? What potential problems can it cause that would not otherwise occur?

pkamb
  • 33,281
  • 23
  • 160
  • 191
Ryan C. Thompson
  • 40,856
  • 28
  • 97
  • 159
  • When [automatic rerere is enabled](http://chuva-inc.com/blog/2012/09/fast-tip-enable-git-rerere-right-now) and it applies a previous resolution, does it display a message? If so, what does it look like? TIA! – joeytwiddle Jun 19 '14 at 01:27
  • 1
    @joeytwiddle, per [this article](https://hackernoon.com/fix-conflicts-only-once-with-git-rerere-7d116b2cec67), it would be of the form, `Resolved 'index.html' using previous resolution.` –  Apr 08 '18 at 09:59

4 Answers4

84

If you do a merge incorrectly, then discard it, then do the "same" merge again, it will be incorrect again. You can forget a recorded resolution, though. From the documentation:

git rerere forget <pathspec>

This resets the conflict resolutions which rerere has recorded for the current conflict in <pathspec>.

Be careful to use it on specific paths; you don't want to blow away all of your recorded resolutions everywhere. (forget with no arguments has been deprecated to save you from doing this, unless you type git rerere forget . to explicitly request it.)

But if you don't think to do that, you could easily end up putting that incorrect merge into your history..

Community
  • 1
  • 1
Tyler
  • 21,762
  • 11
  • 61
  • 90
  • 17
    This is why `rerere` still leaves the files with conflicts marked as unmerged, so that you have to manually add them (hopefully after inspecting/testing them) before committing. You can always use `git checkout -m ` to check out the original conflicted version and redo the resolution if you have to. – Cascabel Apr 02 '11 at 06:15
  • 2
    That would make sense! Sounds like you need a new alias. – Cascabel Apr 02 '11 at 07:01
  • 7
    I think this is probably the main issue. Enabling rerere adds one more way for errors to sneak in unexpectedly. A merge that you abort (or rather undo by deleting it from the history) could still come back to haunt you later. Basically, it introduces a second history mechanism that is orthogonal to the actual history graph. – Ryan C. Thompson Apr 02 '11 at 23:09
  • 3
    @RyanThompson Aborted merges don't affect rerere. (I often wish they did—I've sometimes aborted a merge because I set it up wrong, then needed to do the exact same resolutions when I set it up right.) As for deleting a merge from the history, why would you ever do that? – Marnen Laibow-Koser Feb 11 '14 at 21:49
50

As J. C. Hamano mentions in his article "Fun with rerere" (my bold)

  • Rerere remembers how you chose to resolve the conflicted regions;
  • Rerere also remembers how you touched up outside the conflicted regions to adjust to semantic changes;
  • Rerere can reuse previous resolution even though you were merging two branches with different contents than the one you resolved earlier.

Even people who have been using rerere for a long time often fail to notice the last point.

So if you activate rerere on too broad a content, you might end up with surprising or confusing merge resolution because of the last point.


Another downside was rerere asking you for your pin for GPG signature (if you had activated commit.gpgSign).
This has been fixed with Git 2.38 (Q3 2022)

Guildenstern
  • 2,179
  • 1
  • 17
  • 39
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 18
    The conflicting hunks do still have to match; it's fairly difficult for it to give a false positive. – Cascabel Apr 01 '11 at 23:13
  • And there is `git rerere gc` to forget old resolutions. With shorter time range the probability of mishit is less. – gavenkoa Mar 20 '21 at 23:41
  • 2
    @gavenkoa True (https://git-scm.com/docs/git-rerere#Documentation/git-rerere.txt-emgcem): by default, unresolved conflicts older than 15 days and resolved conflicts older than 60 days are pruned. – VonC Mar 20 '21 at 23:52
5

I've got rerere globally enabled. I really haven't noticed any problems, and it usually seems to make my life easier.

Marnen Laibow-Koser
  • 5,959
  • 1
  • 28
  • 33
3

I cherry picked a commit (in gitk) that only contained a binary file. Cherrypick failed due to conflict (which coming to think about it is natural) and I resolved the conflict keeping the cherry pick. I was surprised later to find in another rebased branch that my dlls did not behave - only to discover they were not carried into the rebase as (I speculate) automatic conflict resolution. So this is the only case I met (having rerere enabled) of running into counterintuitive (though I am sure perfectly consistent) behavior.

Pang
  • 9,564
  • 146
  • 81
  • 122
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361