Git Rerere: wiederkehrende Merge-Konflikte automatisch lösen lassen
AI generated
git
HEAD
Git
Git Rerere
wiederkehrende Merge-Konflikte automatisch lösen lassen

Wer einen lang laufenden Feature-Branch regelmäßig gegen main rebased, kennt das Problem: Derselbe Konflikt in derselben Datei taucht bei jedem Rebase erneut auf. git rerere merkt sich die einmal gefundene Lösung und wendet sie beim nächsten identischen Konflikt automatisch wieder an, ganz ohne externes Werkzeug.

8 Min. Lesezeit Git Merge

1. Was git rerere macht und wofür es gedacht ist

Rerere steht für reuse recorded resolution, also die Wiederverwendung einer bereits aufgezeichneten Konfliktlösung. Sobald die Funktion aktiviert ist, speichert Git bei jedem manuell gelösten Merge-Konflikt den Zustand vor und nach der Auflösung. Taucht später ein Konflikt mit demselben Vorher-Zustand erneut auf, wendet Git die gespeicherte Lösung automatisch an, ohne dass jemand erneut manuell eingreifen muss.

Das Werkzeug greift bei allen Operationen, die Konflikte erzeugen können, also bei git merge, git rebase und git cherry-pick gleichermaßen. Besonders wertvoll wird das bei wiederholten Vorgängen auf demselben Datenbestand, etwa wenn ein Feature-Branch nach jedem Force-Push von main erneut rebased werden muss und dabei immer wieder an derselben Stelle in einer Konfigurationsdatei hakt.

2. rerere aktivieren und den Cache verstehen

Standardmäßig ist rerere in den meisten Git-Installationen deaktiviert und muss explizit eingeschaltet werden, entweder global für alle Repositories oder gezielt für ein einzelnes Projekt. Sobald aktiv, legt Git seinen internen Speicher unter .git/rr-cache an, ein reines lokales Verzeichnis, das nicht Teil der versionierten Projektdateien ist.

Eine zusätzliche Option ist rerere.autoupdate: Ist sie gesetzt, führt Git nach einer automatisch erkannten Konfliktlösung sofort ein implizites git add für die betroffene Datei aus, sodass kein manueller Zwischenschritt mehr nötig ist, um die Auflösung als erledigt zu markieren.


# rerere global für alle Repositories aktivieren
git config --global rerere.enabled true

# automatisches Stagen erkannter Konfliktlösungen zusätzlich aktivieren
git config --global rerere.autoupdate true

3. Der Workflow bei einem wiederkehrenden Konflikt

Beim ersten Auftreten eines Konflikts läuft alles wie gewohnt ab: Git markiert die betroffenen Stellen mit den bekannten Konfliktmarkern, die Konfliktzeilen werden manuell bereinigt, die Datei wird mit git add als gelöst markiert, und der Merge oder Rebase wird fortgesetzt. Im Hintergrund hat rerere in genau diesem Moment bereits den Vorher-Zustand und die gewählte Lösung im Cache abgelegt.

Taucht exakt derselbe Konfliktinhalt zu einem späteren Zeitpunkt erneut auf, etwa weil derselbe Feature-Branch nach einem weiteren Commit auf main erneut rebased wird, erkennt Git den bereits bekannten Konflikt automatisch, wendet die gespeicherte Lösung an und markiert die betroffene Stelle direkt als aufgelöst, ohne dass die Konfliktmarker überhaupt sichtbar werden.


# Nach einem erkannten, automatisch gelösten Konflikt zeigt Git einen Hinweis
git rebase main
# Resolved 'config/app.yaml' using previous resolution.

4. Typische Einsatzszenarien: lange Feature-Branches und Cherry-Pick-Serien

Der klassische Anwendungsfall ist ein Feature-Branch, der über mehrere Wochen parallel zu main entwickelt und dabei regelmäßig neu rebased wird. Wenn dabei immer wieder dieselbe generierte Datei oder dieselbe zentrale Konfigurationsdatei kollidiert, erspart rerere ab dem zweiten Auftreten jede manuelle Wiederholung derselben Konfliktlösung.

Ein zweites häufiges Szenario sind Cherry-Pick-Serien zwischen mehreren Release-Branches, bei denen dieselben Hotfix-Commits auf unterschiedliche, leicht abweichende Branch-Stände angewendet werden müssen. Sobald der erste Cherry-Pick die passende Konfliktlösung liefert, kann rerere dieselbe Lösung bei den folgenden Branches automatisch übernehmen.

5. Den rerere-Cache pflegen: forget, diff und Status prüfen

Für die Übersicht während eines aktiven Konflikts liefert git rerere status die Liste der Pfade, für die eine gespeicherte Lösung gefunden oder verwendet wurde, während git rerere diff zeigt, welche konkreten Änderungen rerere gerade automatisch anwendet, bevor sie tatsächlich übernommen werden.

Wurde eine automatische Auflösung fälschlicherweise übernommen, entfernt git rerere forget <pfad> die betroffene Aufzeichnung gezielt aus dem Cache, sodass beim nächsten Konflikt wieder eine manuelle Entscheidung nötig ist. Alte, lange nicht mehr benötigte Einträge räumt git rerere gc automatisch nach konfigurierbaren Zeiträumen für gelöste und ungelöste Konflikte auf.


# Aktuellen rerere-Status während eines Konflikts anzeigen
git rerere status
git rerere diff

# Eine falsch gelernte Lösung für einen Pfad verwerfen
git rerere forget config/app.yaml

6. Risiken: falsch gelernte Konfliktlösungen automatisch übernehmen

Der größte Schwachpunkt von rerere ist gleichzeitig seine größte Stärke: Es merkt sich exakt das, was einmal manuell entschieden wurde, und zwar unabhängig davon, ob diese Entscheidung inhaltlich richtig war. War die erste Konfliktlösung fehlerhaft, wendet Git dieselbe fehlerhafte Lösung beim nächsten identischen Konflikt still und ohne Rückfrage erneut an.

Gerade bei sicherheitsrelevantem Code oder komplexer Geschäftslogik lohnt es sich deshalb, nach jeder automatisch angewendeten Lösung noch einmal gezielt mit git diff zu prüfen, was tatsächlich übernommen wurde, statt der Automatik blind zu vertrauen. rerere ersetzt kein Code-Review, es beschleunigt nur die mechanische Wiederholung einer bereits einmal getroffenen Entscheidung.

Ein weiterer Grund für Vorsicht: Wird ein Konflikt beim ersten Mal nur oberflächlich gelöst, etwa weil unter Zeitdruck einfach die eigene Variante übernommen wurde, ohne die inhaltliche Bedeutung der anderen Seite zu prüfen, speichert rerere genau diese oberflächliche Entscheidung dauerhaft ab. Ein kurzer Kommentar im Commit, welche Entscheidung getroffen wurde und warum, hilft späteren Beteiligten, die automatisch wiederholte Lösung im Nachhinein besser einordnen zu können.

7. rerere im Team: warum der Cache meist lokal bleibt

Das Verzeichnis .git/rr-cache liegt außerhalb der normalen Projektdateien und wird standardmäßig nicht mit Commits versioniert, wodurch jede Entwicklerin und jeder Entwickler einen eigenständigen, lokalen Cache aufbaut. Das ist in den meisten Fällen auch sinnvoll, da Konfliktlösungen oft von individuellen lokalen Branch-Ständen abhängen, die zwischen Teammitgliedern variieren.

In Ausnahmefällen, etwa bei einem sehr großen Team, das denselben bekannten Konflikt in einer generierten Datei immer wieder unabhängig voneinander löst, lässt sich der Cache technisch auch über ein eigenes Verteilungsskript teilen, in der Praxis ist das aber die Ausnahme und keine Standardempfehlung.

8. Den Cache mit einem Trainings-Skript vorab befüllen

Im contrib-Verzeichnis der Git-Quellen liegt ein Skript namens rerere-train.sh, das die komplette bestehende Merge-Historie eines Repositories durchgeht, jeden historischen Merge-Commit erneut simuliert und die dabei entstehenden Konfliktlösungen in den lokalen rerere-Cache einspeist.

Das ist besonders nützlich direkt nach dem frischen Klonen eines Repositories, dessen Team bereits bekannte, wiederkehrende Konflikte hat: Statt jeden dieser Konflikte erneut manuell zu lösen, füllt das Trainings-Skript den Cache im Voraus, sodass rerere schon beim ersten eigenen Rebase greifen kann.


# Bestehende Merge-Historie einmalig für rerere trainieren
./rerere-train.sh $(git rev-list --all --merges)

9. Abgrenzung zu Merge-Strategien und benutzerdefinierten Mergern

rerere ersetzt keine inhaltlichen Merge-Strategien wie einen merge=union-Treiber in .gitattributes, der für bestimmte Dateitypen von vornherein definiert, wie Änderungen automatisch zusammengeführt werden sollen. Ein solcher Treiber wendet eine allgemeine Regel an, bevor überhaupt ein Konflikt entsteht.

rerere setzt dagegen erst an, nachdem ein Konflikt tatsächlich aufgetreten und einmal manuell gelöst wurde, und wiederholt danach exakt diese konkrete, bereits getroffene Entscheidung. Beide Mechanismen ergänzen sich gut: Ein Merge-Treiber deckt vorhersehbare, generische Fälle ab, rerere übernimmt die individuellen, wiederkehrenden Konflikte, die sich nicht pauschal per Regel lösen lassen.

Merkmal git rerere merge=union Treiber Manuelles Wiederholen
Wirkt vor oder nach dem Konflikt Nach dem ersten manuellen Lösen Vor dem Entstehen des Konflikts Bei jedem Auftreten erneut
Speicherort der Lösung Lokaler Cache unter .git/rr-cache Regel in .gitattributes, versioniert Nirgends, jedes Mal neu
Geeignet für individuelle Konflikte Ja, exakte Vorher-Nachher-Zustände Nein, nur generische Regeln Ja, aber zeitaufwendig
Automatisierungsgrad Hoch, nach dem ersten Mal automatisch Hoch, aber nur regelbasiert Keiner

Mironsoft

Git-Workflows, Branching-Strategien und CI-Hooks

Chaotische Git-Historie und unklare Branching-Regeln im Team?

Wir richten saubere Git-Workflows ein, klären Branching-Strategien fürs Team und automatisieren Qualitätschecks über Git-Hooks und CI-Pipelines, damit die Historie nachvollziehbar bleibt.

Workflow-Audit

Bestehende Branching-Strategie und Merge-Praxis auf Schwachstellen prüfen.

Hook-Automatisierung

Pre-Commit- und Pre-Push-Hooks für Linting, Tests und Commit-Konventionen einrichten.

Team-Schulung

Rebase, Cherry-Pick und Konfliktauflösung im Team praxisnah vermitteln.

10. Zusammenfassung

Git Rerere

Kernidee

git rerere merkt sich eine einmal manuell gefundene Konfliktlösung und wendet sie bei identischen Konflikten automatisch erneut an.

Aktivierung

git config rerere.enabled true schaltet den Mechanismus ein, der Cache liegt lokal unter .git/rr-cache.

Typischer Einsatz

Lang laufende Feature-Branches mit wiederholtem Rebase und Cherry-Pick-Serien über mehrere Release-Branches.

Wichtige Regel

Automatisch angewendete Lösungen dennoch per git diff prüfen, rerere wiederholt auch eine ursprünglich falsche Entscheidung.

11. FAQ: Git Rerere

1Muss rerere für jedes Repository einzeln aktiviert werden?
Nein, mit git config --global rerere.enabled true wird die Funktion für alle Repositories auf dem eigenen Rechner aktiv, eine repository-spezifische Aktivierung ohne --global ist aber ebenfalls möglich.
2Wo liegt der rerere-Cache und wird er versioniert?
Der Cache liegt unter .git/rr-cache innerhalb jedes Repositories und wird standardmäßig nicht mit committet, da er außerhalb der normal versionierten Projektdateien liegt.
3Funktioniert rerere auch bei cherry-pick, nicht nur bei merge und rebase?
Ja, rerere greift bei allen drei Operationen gleichermaßen, da alle drei intern denselben Drei-Wege-Merge-Mechanismus nutzen, auf dem rerere aufsetzt.
4Was passiert, wenn eine automatisch angewendete Lösung falsch war?
Mit git rerere forget und dem betroffenen Pfad lässt sich die fehlerhafte Aufzeichnung gezielt aus dem Cache entfernen, sodass beim nächsten Auftreten wieder manuell entschieden werden muss.
5Muss ich nach einer automatisch gelösten Konfliktdatei trotzdem git add ausführen?
Nur wenn rerere.autoupdate nicht aktiviert ist, mit dieser Option führt Git das Staging der automatisch aufgelösten Datei selbstständig aus.
6Lohnt sich rerere auch bei kurzen, selten rebasten Branches?
Kaum, der eigentliche Nutzen entsteht erst, wenn derselbe Konflikt tatsächlich mehrfach auftritt, bei einem einmaligen Merge gibt es schlicht keine Wiederholung, die rerere abkürzen könnte.
7Kann der rerere-Cache im Team geteilt werden?
Technisch ja, über ein eigenes Verteilungsskript, in der Praxis bleibt der Cache aber fast immer lokal, da Konfliktlösungen oft vom individuellen Branch-Stand einer einzelnen Person abhängen.
8Was macht das Skript rerere-train.sh genau?
Es simuliert die vorhandene Merge-Historie eines Repositories erneut und speist die dabei entstehenden Konfliktlösungen in den lokalen rerere-Cache ein, bevor der eigentliche Alltag mit rerere beginnt.
9Ersetzt rerere ein Code-Review nach einer automatischen Konfliktlösung?
Nein, rerere beschleunigt nur die mechanische Wiederholung einer bereits einmal getroffenen Entscheidung, ein Blick mit git diff auf das tatsächliche Ergebnis bleibt weiterhin sinnvoll.
10Räumt Git den rerere-Cache irgendwann automatisch auf?
Ja, git rerere gc entfernt alte Einträge nach konfigurierbaren Zeiträumen für gelöste und für ungelöste Konflikte und läuft in der Regel automatisch im Rahmen der regulären Git-Wartung mit.