Ein erzwungener Push hat fremde Commits überschrieben. Die Arbeit ist meist noch da – im Reflog derjenigen, die sie hatten.
Aufwand:
ca. 45 Min.
Voraussetzung:
Externes Backup-Medium
Gilt für:
Git (alle aktuellen Versionen)
Das Symptom
Nach einem erzwungenen Push sind die Commits mehrerer Kollegen aus dem Zweig
verschwunden. Die Arbeit eines halben Tages ist im gemeinsamen Repository nicht mehr
auffindbar, und die ersten Nachrichten im Chat werden hektisch.
Die „Layer 8“-Wahrheit
Zuerst die gute Nachricht, und sie ist besser, als die Panik im Chat vermuten lässt:
Git vernichtet Commits nicht, es hört nur auf, auf sie zu zeigen. Ein erzwungener Push
verschiebt einen Zeiger. Die eigentlichen Commits sind zunächst noch da – auf dem
Server für eine Weile, und vor allem auf jedem Rechner, der sie hatte. Das Reflog
ist ein Logbuch darüber, wo ein Zweig überall schon einmal stand, und aus diesem
Logbuch lässt sich der verlorene Stand fast immer zurückholen.
Deshalb ist der wichtigste Handgriff auch kein Git-Befehl, sondern eine Nachricht an
alle: Zieht jetzt bitte nicht. Denn wer nach dem Unfall aktualisiert, ersetzt womöglich
seinen eigenen, noch heilen Stand durch den beschädigten – und schneidet damit genau
den Ast ab, auf dem die Rettung sitzt.
Und die eigentliche Lehre: --force ist ein Befehl, der sagt „mir egal, was dort
steht“. Es gibt eine bessere Variante, die praktisch niemand benutzt, weil sie länger
zu tippen ist. --force-with-lease erzwingt nur dann, wenn seit dem letzten Blick
niemand anders etwas veröffentlicht hat. Sie hätte diesen Unfall verhindert, und sie
verhindert den nächsten – zum Preis von elf zusätzlichen Zeichen.
Die echte, verifizierte Lösung
1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:
1.
Sofort Bescheid geben
Der erste Schritt ist keine Technik, sondern Kommunikation: allen sagen, dass sie nicht ziehen sollen. Wer nach einem überschreibenden Push aktualisiert, kann seinen lokalen Stand mit dem beschädigten überschreiben – und dann geht die Rettungsleine verloren.
2.
Die verlorenen Commits finden
Git vergisst nichts sofort. Das Reflog zeichnet auf, wo ein Zweig zuletzt stand – auch dort, wohin er nicht mehr zeigt. Auf dem Rechner, der die verlorenen Commits noch hatte, steht der alte Stand darin.
git reflog
3.
Den alten Stand wiederherstellen
Ist der Hash des letzten guten Commits gefunden, lässt sich der Zweig dorthin zurücksetzen und der korrekte Stand wieder veröffentlichen. Vorher unbedingt einen Sicherungszweig anlegen.
git branch rettung <hash>
4.
Statt zu erzwingen, mit Vorbehalt erzwingen
Ein erzwungener Push ist manchmal nötig, etwa nach einem Rebase des eigenen Zweigs. Dann aber nur in der Variante, die abbricht, sobald jemand anders inzwischen etwas veröffentlicht hat. Sie verhindert genau diesen Unfall.
git push --force-with-lease
5.
Den Hauptzweig schützen
Auf gemeinsam genutzten Zweigen sollte ein erzwungener Push technisch unmöglich sein. Alle gängigen Plattformen bieten dafür einen Schutz – das ist keine Bevormundung, sondern eine Leitplanke gegen einen sehr teuren Fehler.
Häufige Fragen (FAQ)
?Sind die Commits jetzt für immer weg?
Meistens nicht. Solange jemand die Commits noch lokal hatte, stehen sie in seinem Reflog und lassen sich zurückholen. Auf dem Server sind sie zunächst nur nicht mehr erreichbar, aber oft noch vorhanden – bis die Aufräumroutine sie irgendwann entfernt. Deshalb zählt Geschwindigkeit.
?Was ist der Unterschied zu --force-with-lease?
Ein blindes --force sagt: Überschreibe, egal was dort steht. Mit --force-with-lease sagt Git: Überschreibe nur, wenn der Zweig noch genau dort steht, wo ich ihn zuletzt gesehen habe. Hat jemand anders inzwischen gepusht, bricht der Vorgang ab – exakt der Schutz, der hier gefehlt hat.
Belege
Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.
Der Diff markiert jede Zeile als geändert, obwohl nur ein Wort angepasst wurde? Zeilenenden. Windows und Unix streiten sich um ein unsichtbares Zeichen.
Git meldet „detached HEAD“? Du stehst nicht auf einem Branch, sondern direkt auf einem Commit — Änderungen hier gehen ohne Gegenmaßnahme leicht verloren.