← Zur Uebersicht

Git-Reparatur: einen zu grossen Commit sinnvoll aufteilen

Beim Arbeiten am Verbesserungsplan kann es passieren, dass mehrere fachliche Themen versehentlich in einem Sammelcommit landen. Das ist kein Grund, die Projektdateien zu verlieren: Die Commit-Historie kann lokal neu geordnet werden, waehrend der Arbeitsstand erhalten bleibt.

Ausgangssituation

Ein Sammelcommit enthaelt zum Beispiel CI-Aenderungen, OpenShift-Haertung, Frontend-Refactoring und Dokumentation. Fuer Review, Fehlersuche und spaetere Ruecknahmen ist eine fachliche Trennung besser.

Sicherer Reparaturablauf

  1. Zuerst den Zustand pruefen:

powershell git status --short --branch git log --oneline -n 5

  1. Den letzten lokalen Sammelcommit zuruecknehmen, aber die Dateien behalten:

powershell git reset --soft HEAD~1 git reset

--soft verschiebt nur den Branch-Zeiger und laesst alle Aenderungen staged. Das anschliessende git reset nimmt nur das Staging zurueck. Die Dateien bleiben als Arbeitsstand erhalten.

  1. Die Dateien thematisch gruppieren und einzeln committen:

```powershell git add Jenkinsfile ci/scripts/quality-check.ps1 novaris-legacy-parent novaris-modern-parent/Jenkinsfile novaris-modern-parent/pom.xml git commit -m "ci: tests und pipelines container-runtime-neutral machen"

git add novaris-modern-parent/novaris-policy-core-modern novaris-modern-parent/openshift git commit -m "feat: Prometheus-Metriken und OpenShift-Haertung ergaenzen"

git add novaris-modern-parent/novaris-policy-web-modern-spa git commit -m "refactor: SPA-Build und Auth-Kontext stabilisieren"

git add docs index.html git commit -m "docs: Verifikation und Verbesserungsstatus aktualisieren" ```

Vor jedem Commit sollte git diff --cached kontrollieren, ob wirklich nur das beabsichtigte Thema enthalten ist. Die Commit-Reihenfolge folgt dabei den Abhaengigkeiten: erst CI, dann Plattform, dann Frontend und zuletzt die zusammenfassende Dokumentation.

  1. Die neue Historie lokal pruefen:

powershell git diff --check git log --oneline --decorate -n 10 git status --short --branch

  1. Wenn der Sammelcommit bereits auf dem Remote lag, muss der Branch mit --force-with-lease aktualisiert werden:

powershell git push --force-with-lease origin master

--force-with-lease ist sicherer als ein blindes --force: Der Push wird abgelehnt, wenn jemand den Remote-Branch seit dem letzten Abruf veraendert hat. Bei einem gemeinsam genutzten Branch sollte man alternativ einen neuen Branch und Pull Request verwenden.

Was dabei gelernt wird

Weitere typische Reparaturfaelle

1. Rebase auf den aktuellen Zielbranch

Der eigene Feature-Branch ist veraltet und soll vor dem Pull Request auf den aktuellen master gesetzt werden:

git fetch origin
git switch feature/mein-thema
git rebase origin/master

Bei Konflikten stoppt der Rebase. Nach der manuellen Korrektur geht es so weiter:

git status
git add <korrigierte-datei>
git rebase --continue

Den Rebase kann man vollständig abbrechen, ohne den Zustand vor dem Rebase zu verlieren:

git rebase --abort

Nach einem erfolgreichen Rebase hat der Feature-Branch neue Commit-IDs. Ein bereits gepushter Feature-Branch wird deshalb mit --force-with-lease aktualisiert.

2. Merge-Konflikt Schritt fuer Schritt loesen

Bei einem normalen Merge:

git fetch origin
git switch master
git merge origin/master

Git markiert Konflikte im Arbeitsbaum. In den betroffenen Dateien stehen dann Markierungen wie <<<<<<< HEAD, ======= und >>>>>>> origin/master. Die richtige Loesung wird fachlich zusammengesetzt; die Marker muessen vollstaendig entfernt werden.

git diff
git add <geloeste-datei>
git diff --cached
git commit

Wenn die Konfliktloesung falsch begonnen wurde:

git merge --abort

Vor dem Commit helfen Tests und git diff --check, weil ein konfliktfreier Merge noch keine fachlich korrekte Loesung garantiert.

3. Falsches Staging rueckgaengig machen

Eine Datei wurde versehentlich gestaged, soll aber im Arbeitsbaum bleiben:

git restore --staged <datei>

Nur eine einzelne Aenderung innerhalb einer Datei soll aus dem Staging entfernt werden:

git restore --staged --patch <datei>

Die Aenderung ist damit nicht geloescht. Sie liegt weiterhin im Working Tree und kann spaeter gezielt erneut gestaged werden.

4. Falsche Commit-Nachricht oder letzter Commit

Nur die Nachricht des letzten, noch nicht geteilten Commits korrigieren:

git commit --amend -m "korrekte nachricht"

Eine vergessene Datei kann ebenfalls mit --amend --no-edit nachgetragen werden. Das sollte nur fuer den letzten Commit verwendet werden. Sobald andere Personen den Commit bereits verwenden, ist ein neuer Korrektur-Commit meist sicherer.

5. Einen Commit teilen oder zusammenfassen

Mehrere kleine lokale Commits koennen vor dem Push interaktiv neu geordnet, zusammengefasst oder umbenannt werden:

git rebase -i HEAD~4

Im Editor bedeuten pick behalten, reword Nachricht aendern, edit anhalten, squash mit dem vorherigen Commit verbinden und drop entfernen. Fuer einen zu grossen letzten Commit ist der dokumentierte reset --soft-Weg oft uebersichtlicher, weil danach jede fachliche Gruppe neu gestaged wird.

6. Versehentlich geloeschte oder verschobene Arbeit finden

Wenn ein Reset, Rebase oder Checkout scheinbar einen Commit verschwinden liess, zeigt das Reflog die frueheren Positionen von HEAD:

git reflog --date=local
git show <alte-head-id>
git switch -c recovery/<kurze-beschreibung> <alte-head-id>

Erst auf dem Wiederherstellungs-Branch pruefen, dann einzelne Dateien oder Commits zurueckholen. Nicht sofort erneut resetten, bevor die alte Commit-ID gesichert ist.

7. Push abgelehnt: Remote ist weiter

Bei non-fast-forward zuerst den Remote-Stand ansehen:

git fetch origin
git log --oneline --graph --decorate --all -n 20

Fuer einen Feature-Branch ist ein Rebase auf den Remote-Stand meist passend:

git rebase origin/feature/mein-thema
git push --force-with-lease origin feature/mein-thema

Auf master sollte man normalerweise nicht ueberschreiben. Dort ist ein Merge- oder Pull-Request-Weg sicherer. Ein Force-Push ist nur dann angemessen, wenn die Historie bewusst repariert werden soll und alle Beteiligten davon wissen.

8. Sicherheitsregel fuer jede Reparatur

Vor einem reset, rebase oder force push zuerst einen Sicherungspunkt anlegen:

git status --short --branch
git branch backup/vor-git-reparatur
git log --oneline --decorate -n 10

Die Backup-Referenz ist lokal und veraendert keine Dateien. Sie kann nach erfolgreicher Pruefung geloescht werden:

git branch -d backup/vor-git-reparatur

Merksatz

Erst Zustand sichern und pruefen, dann den Zeiger verschieben, anschliessend thematisch stagen, jeden Commit pruefen und erst am Ende den Remote-Branch aktualisieren.

⌂ Cockpit