git squash commits on branch

git squash commits on branch

Stell dir vor, es ist Freitagabend, 17:30 Uhr. Dein Team will ein kritisches Feature in den Hauptzweig schieben. Du entscheidest dich für Git Squash Commits On Branch, um die 45 "WIP"- und "Fix typo"-Nachrichten loszuwerden, die deine Historie verstopfen. Du drückst den Knopf, löschst den alten Branch und plötzlich stellt ein Kollege fest, dass eine wichtige Änderung aus einem parallelen Hotfix verschwunden ist. Da du die gesamte Historie zu einem einzigen Klumpen verschmolzen hast, gibt es kein Zurück mehr. Du verbringst die nächsten vier Stunden damit, im Reflog zu wühlen, während dein Chef im Minutentakt fragt, warum die Pipeline brennt. Ich habe das in Projekten mit Budgets im siebenstelligen Bereich erlebt: Ein einziger falsch ausgeführter Squash kann ein Team zwei Tage produktive Arbeit kosten, nur weil jemand eine "saubere" Liste wollte.

Die Falle der kosmetischen Sauberkeit

Viele Entwickler glauben, dass ein sauberer Commit-Log das höchste Gut in der Softwareentwicklung ist. Das ist ein Irrtum. Der Log ist ein Werkzeug zur Fehlersuche, kein Poesiealbum. Wenn du Git Squash Commits On Branch nur deshalb nutzt, damit die Grafik im Interface schöner aussieht, handelst du fahrlässig.

In meiner Laufbahn habe ich oft gesehen, wie Junioren (und leider auch Senioren) zwanzig kleine, logisch getrennte Änderungen in ein riesiges Paket stopfen. Das Problem dabei: Wenn später ein Fehler auftritt, kannst du git bisect vergessen. Du findest zwar den Commit, der den Fehler enthält, aber dieser Commit ist 4.000 Zeilen lang und enthält Änderungen an der Datenbank, der UI und der Authentifizierung. Du hast die Granularität geopfert, um eitel zu wirken. Ein guter Commit sollte so klein wie möglich und so groß wie nötig sein. Das Zusammenführen macht nur Sinn, wenn die einzelnen Schritte für sich genommen instabil oder völlig aussagelos sind.

Risiken beim Git Squash Commits On Branch in geteilten Umgebungen

Hier begehen die meisten den kardinalen Fehler: Sie führen einen Squash auf einem Branch aus, an dem mehr als eine Person arbeitet. In Git ist ein Squash technisch gesehen ein Rewrite der Historie. Sobald du das tust und einen force push ausführst, ziehst du deinen Kollegen den Boden unter den Füßen weg.

Ich erinnere mich an ein Projekt in München, bei dem ein externer Berater genau das tat. Er wollte den Branch aufräumen, bevor er ihn übergab. Drei andere Entwickler hatten jedoch bereits auf Basis seines alten Stands weitergearbeitet. Das Ergebnis war ein Merge-Konflikt-Albtraum, der die Integration um eine ganze Woche verzögerte. Die Regel ist simpel: Wenn der Branch den lokalen Rechner verlassen hat und andere darauf zugreifen, bleibt die Historie, wie sie ist. Wer hier aus ästhetischen Gründen squasht, verbrennt Geld.

Der Mythos des perfekten Rebase

Oft wird behauptet, dass ein interaktiver Rebase die Lösung für alles sei. Das stimmt nur, wenn man die Konsequenzen versteht. Ein Rebase während man die Historie vereint, ändert die Commit-Hashes. Wenn du das auf einem Branch machst, der bereits einen Pull Request offen hat, zerstörst du die Review-Historie. Die Kommentare der Reviewer beziehen sich plötzlich auf Code-Zeilen, die in den neuen Hashes nicht mehr existieren oder verschoben wurden. Der Reviewer muss also von vorne anfangen. Rechne das mal hoch: Drei Reviewer brauchen jeweils 30 Minuten länger. Das sind 90 Minuten verschwendete Zeit pro Squash-Aktion.

Warum die Standard-Einstellung in GitHub und GitLab gefährlich ist

Plattformen wie GitHub bieten einen großen grünen Button "Squash and Merge". Das ist für kleine Open-Source-Beiträge nett, in einer professionellen Enterprise-Umgebung ist es oft Gift. Der Grund ist die Art und Weise, wie Git Merges verfolgt.

Wenn du Git Squash Commits On Branch über die Weboberfläche ausführst, verliert Git oft den Bezug zum ursprünglichen Feature-Branch. Wenn du später einen Revert machen musst, wird es kompliziert. Du kannst nicht einfach den einen fehlerhaften Teil des Features rückgängig machen, weil alles in einem Block verschweißt wurde. In meiner Praxis habe ich Teams gesehen, die deshalb ganze Sprints wiederholen mussten, weil sie ein instabiles Teil-Feature nicht isoliert entfernen konnten. Die Automatik der Tools verleitet dazu, den Kopf auszuschalten.

Ein Vorher-Nachher-Vergleich aus der echten Welt

Schauen wir uns an, wie dieser Prozess in der Realität den Unterschied macht.

Stell dir vor, Entwickler A arbeitet an einem Login-System. Er macht fünf Commits:

  1. Basis-Struktur
  2. API-Anbindung
  3. Fehlerbehandlung
  4. CSS-Fixes
  5. Refactoring der API-Anbindung.

Beim falschen Ansatz macht er einen Squash zu einem einzigen Commit mit der Nachricht "Login-System implementiert". Zwei Wochen später wird ein Sicherheitsleck in der API-Anbindung gefunden. Da alles ein Block ist, muss der Entwickler mühsam die 15 Dateien durchsuchen, die zum Login gehören. Er muss den Code manuell sezieren, um zu verstehen, was er sich beim Refactoring im Vergleich zur ursprünglichen API-Anbindung gedacht hat. Die Fehlersuche dauert sechs Stunden, weil der Kontext der schrittweisen Entwicklung fehlt.

Beim richtigen Ansatz erkennt der Entwickler, dass Punkt 4 und 5 eigentlich Korrekturen zu 2 und 3 sind. Er führt gezielt nur diese Commits zusammen. Am Ende hat er drei saubere Commits: Basis-Struktur, API-Anbindung (inklusive Refactoring) und die Fehlerbehandlung (inklusive CSS-Fix). Als das Sicherheitsleck auftaucht, schaut er sich gezielt den zweiten Commit an. Er sieht sofort die Logik hinter der API-Anbindung ohne das Rauschen der UI-Änderungen. Die Reparatur dauert 20 Minuten. Der Unterschied sind über fünf Stunden Arbeitszeit, nur weil man selektiv und logisch statt blind und massiv vorgegangen ist.

Die verlorene Kunst der Commit-Nachricht

Ein Squash wird oft als Entschuldigung für schlechte Commit-Nachrichten missbraucht. "Ich schreibe jetzt einfach Müll rein, ich squashe das ja später sowieso." Das ist eine gefährliche Einstellung. Wenn du während der Entwicklung keine Disziplin hältst, wirst du beim finalen Zusammenführen der Commits wichtige Details vergessen.

In einem Fall bei einem großen deutschen Automobilzulieferer wurde ein kritischer Hinweis zu einer Abhängigkeit in einer unsauberen Commit-Nachricht versteckt. Beim Squash wurde dieser Hinweis gelöscht, weil der Entwickler dachte, er sei unwichtig. Monate später stürzte das System ab, weil genau diese Abhängigkeit fehlte. Hätte man die Historie sinnvoll gepflegt, statt sie am Ende plattzuwalzen, wäre der Hinweis noch da gewesen. Ein Squash sollte Informationen verdichten, nicht vernichten.

Das Problem mit den Metadaten

Jeder Commit in Git speichert den Autor und den Zeitstempel. Wenn du fünf Commits von drei verschiedenen Tagen zusammenfasst, verlierst du die zeitliche Abfolge deiner Arbeit. Das mag unwichtig klingen, bis du beweisen musst, warum eine bestimmte Entscheidung an einem Dienstag getroffen wurde (vielleicht nach einem Meeting mit dem Kunden). Wer blind squasht, löscht die digitale Spur der Entscheidungsfindung.

Strategien für den Umgang mit Merge-Konflikten

Ein massiver Squash am Ende eines langen Branch-Lebenszyklus provoziert Konflikte, die kaum noch lösbar sind. Wenn du zwei Wochen lang auf einem Branch arbeitest und dann versuchst, alles in einen Commit zu pressen, während sich der Hauptzweig weiterentwickelt hat, ist das wie ein Autounfall in Zeitlupe.

In meiner Zeit als Lead Developer habe ich Folgendes gelernt: Wer früh und oft den Hauptzweig in seinen Branch integriert, ohne zu squashen, hat weniger Schmerzen. Der Squash sollte der allerletzte Schritt sein, unmittelbar bevor der Branch endgültig verschwindet. Wer zu früh squasht, beraubt sich der Möglichkeit, Konflikte inkrementell zu lösen. Es gibt nichts Schlimmeres als einen 500-Dateien-Konflikt in einem einzigen Squash-Commit zu lösen. Die Wahrscheinlichkeit, dass du dabei Code deiner Kollegen versehentlich löschst, liegt bei fast 100 Prozent.

Realitätscheck

Hand aufs Herz: Die meisten Teams setzen Git Squash Commits On Branch falsch ein. Sie nutzen es als Pflaster für mangelnde Disziplin während der Entwicklung. Aber kein Tool der Welt kann fehlende Planung ersetzen.

Wenn du wirklich erfolgreich mit Git arbeiten willst, musst du akzeptieren, dass Ordnung Zeit kostet. Es gibt keine magische Abkürzung, die am Ende alles "sauber" macht, ohne dass du zwischendurch Gehirnschmalz investieren musst. In der echten Welt bedeutet Erfolg mit dieser Strategie, dass du dir bei jedem einzelnen Commit überlegst: "Versteht mein Kollege in zwei Jahren, warum ich das hier tue?"

Wenn die Antwort "Nein" lautet, hilft auch kein Squash. Du musst lernen, atomare Commits zu schreiben. Ein Squash ist ein Skalpell, kein Vorschlaghammer. Wer ihn wie einen Hammer benutzt, macht mehr kaputt, als er repariert. Am Ende des Tages interessiert es niemanden, wie schön dein Git-Graph aussieht, wenn die Software voller Bugs ist, die man wegen einer zerstörten Historie nicht mehr nachverfolgen kann. Bleib pragmatisch, behalte die Granularität, wo sie nötig ist, und räum nur dort auf, wo es den Informationsgehalt wirklich erhöht. Alles andere ist Zeitverschwendung und teure Eitelkeit.

NW

Nina Wagner

Nina Wagner verbindet redaktionelle Sorgfalt mit erzählerischer Klarheit und macht relevante Themen greifbar.