Inspecting the rerere cache Jump to heading
Most people use rerere as a black box: enable it, and conflicts sometimes resolve themselves. That works until something goes wrong β a resolution is reused where it should not be, a resolution you expected is missing, the cache seems to have forgotten everything. Then you need to look inside. The cache is plain files in a directory, one subdirectory per conflict, each holding the conflicted text and the resolved text. Understanding that layout makes rerere predictable: you can see what it knows, find the entry behind a particular reuse, and edit or remove it by hand. This page walks through the structure and the commands that read it, within rerere conflict automation.
When to use this approach Jump to heading
- rerere reused a resolution and you want to see exactly what it recorded.
- An expected resolution was not reused and you want to know why.
- You want to remove an entry without being in the middle of the conflict.
- You are preparing to share the cache, as in sharing rerere resolutions across a team, and want to know what you would be sharing.
Step 1 β Find the cache directory Jump to heading
The cache lives in the common Git directory, shared by all worktrees of a repository.
cache="$(git rev-parse --git-common-dir)/rr-cache"
ls "$cache" | head
ls "$cache" | wc -l Each subdirectory name is a hash β the conflict ID. It is computed from the conflicting hunksβ content, normalised so that which side is βoursβ and which is βtheirsβ does not matter. The same conflict in a merge and in the reverse merge produces the same ID.
Step 2 β Read an entryβs files Jump to heading
An entry contains up to three kinds of files.
d="$cache/$(ls -t "$cache" | head -1)"
ls -l "$d"
sed -n '1,30p' "$d/preimage"
diff -u "$d/preimage" "$d/postimage" The diff between preimage and postimage is the resolution as rerere will apply it: it removes the markers and keeps whatever you kept.
Step 3 β Find the entry behind a specific conflict Jump to heading
During a conflicted operation, git rerere status lists files rerere is tracking and git rerere remaining lists those still needing resolution. To find the entry for a file, match its conflict text against preimages.
git rerere status
git rerere remaining
# Which entry has a preimage containing this file's conflicting line?
grep -l 'max_connections' "$cache"/*/preimage* | sed 's#/preimage.*##' | sort -u Outside an operation, search postimages for text you remember from the resolution.
grep -l 'skip_discount=invoice.is_credit_note' "$cache"/*/postimage* | xargs -n1 dirname | sort -u Step 4 β Understand why a resolution was not reused Jump to heading
When rerere does not reuse a resolution you expected, one of three things happened: the conflict text differs slightly (a new line inside the hunk changes the ID), the entry expired, or rerere was not enabled when you resolved it the first time.
# Was rerere enabled at all in this repository?
git config --get rerere.enabled
# Are there entries older than the default resolved-expiry of 60 days?
find "$cache" -name postimage -mtime +60 | wc -l
# Unresolved entries (preimage, no postimage) β conflicts never seen resolved
for e in "$cache"/*/; do [ -e "$e/postimage" ] || echo "unresolved: $(basename "$e")"; done Expiry is controlled by gc.rerereResolved (sixty days by default) and gc.rerereUnresolved (fifteen days), applied when git gc or git rerere gc runs.
Step 5 β Edit or remove entries by hand Jump to heading
Because entries are plain files, you can correct a postimage directly or remove an entry entirely. This is useful when the conflict is not in front of you, so git rerere forget cannot be used.
# Correct a recorded resolution in place
$EDITOR "$cache/<conflict-id>/postimage"
# Remove an entry entirely
rm -r "$cache/<conflict-id>"
# Prune expired entries now rather than waiting for gc
git rerere gc β οΈ SAFETY WARNING: Editing a postimage changes what rerere will silently apply in future merges and rebases. Make the edit carefully and keep a copy of the original (
cp postimage postimage.bak). Removing an entry cannot be undone without a backup of the cache directory.
Step 6 β Audit the cache before sharing it Jump to heading
Before copying a cache to teammates or CI, check that it contains only resolutions worth spreading. List each resolved entry with the first changed line of its resolution, which is usually enough to recognise what it is for.
for e in "$cache"/*/; do
[ -f "$e/postimage" ] || continue
first=$(diff "$e/preimage" "$e/postimage" | grep '^>' | head -1 | cut -c3-80)
printf '%s %s\n' "$(basename "$e" | cut -c1-10)" "$first"
done | sort -k2 | less Remove anything you do not recognise or would not stand behind, and anything resolved for a branch that no longer exists. A small, trusted cache spreads good resolutions; a large, unexamined one spreads old mistakes.
Validation checklist Jump to heading
Frequently Asked Questions Jump to heading
Is the cache shared between clones? Jump to heading
No. Each clone has its own rr-cache. Worktrees of the same clone share it. Sharing between clones requires copying the directory or training from merge commits.
Can the same conflict have more than one recorded resolution? Jump to heading
Yes. If you resolve the same conflict ID differently in different contexts, rerere stores numbered variants and tries to pick the one whose preimage matches the current conflict exactly.
Does rerere store whole files? Jump to heading
No, only the conflicted regions with enough context to identify them. That is why the cache stays small even after years of use.
Related Jump to heading
- Rerere Conflict Automation β the parent topic.
- Forgetting a Bad rerere Resolution β removing entries during a conflict.
- Training rerere from Existing Merge History β populating the cache from history.
- Recovering Unreachable Objects with git fsck β another part of .git worth knowing your way around.