Layer 8Ehrlicher Tech-Support

force push hat die Arbeit der Kollegen gelöscht

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. 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. 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. 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. 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. 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.

Zuletzt geprüft am . Dokumentation altert – ein Datum daneben ist der einzige ehrliche Umgang damit.

Auch zu finden unter

Verwandte Fehler

SWLästigdetached HEAD

Git: detached HEAD state

Git meldet „detached HEAD“? Du stehst nicht auf einem Branch, sondern direkt auf einem Commit — Änderungen hier gehen ohne Gegenmaßnahme leicht verloren.