Ein solider git workflow ist die günstigste Investition, die du in die Codebasis eines Teams tätigen kannst. Allein arbeitend richtet es keinen Schaden an, alles direkt nach main zu pushen; doch sobald zwei Personen dieselbe Datei anfassen, bleibt die Frage, wer was wann geändert hat, unbeantwortet. Ein auf Feature-Branches und Pull Requests aufgebauter Ablauf existiert genau dafür, dieses Chaos zu verhindern: Jede Arbeit wächst auf ihrem eigenen Branch, und der Hauptbranch bricht nie, bevor jemand die Änderung gesehen hat.
In diesem Leitfaden beschreibe ich einen einfachen, aber disziplinierten Ablauf, der für jede Art von Team funktioniert, von Metin2-Serverprojekten bis zu Laravel-Webanwendungen. Das Ziel ist nicht, schicke Befehle auswendig zu lernen; es geht darum, im Wissen zu arbeiten, was man tut und warum.
Warum ein Feature-Branch?
Der Hauptbranch (main oder master) muss stets auslieferbar sein. Alles, was du daraus auscheckst, sollte sich bauen und ausführen lassen. Geschützt wird das, indem man unfertige Arbeit aus dem Hauptbranch heraushält. Jedes neue Feature, jede Fehlerbehebung oder jedes Experiment lebt auf seinem eigenen Branch:
- Der Hauptbranch bleibt intakt; die Produktion kann jederzeit daraus deployt werden.
- Zwei parallel arbeitende Personen sehen nie den halb geschriebenen Code des anderen.
- Wird ein Feature verworfen, genügt das Löschen des Branches; auf main bleibt keine Spur.
- Jeder Branch ist ein in sich geschlossener Satz von Änderungen, der unabhängig reviewt werden kann.
Einen Branch anlegen und benennen
Aktualisiere vor dem Start den Hauptbranch und lege dann davon einen neuen Branch an. In modernem Git ist das ein einziger Befehl:
git switch main
git pull --ff-only
git switch -c feature/benutzer-login
git switch -c erstellt den Branch und wechselt darauf; das ältere git checkout -b tut dasselbe. Ein konsistentes Präfix in Branch-Namen zeigt beim Überfliegen der Liste sofort die Art der Arbeit:
feature/— ein neues Featurefix/— eine Fehlerbehebungchore/— Abhängigkeiten, Konfiguration, Aufräumenrefactor/— interne Umstrukturierung, die das Verhalten nicht ändert
Halte den Namen kurz, aber aussagekräftig: fix/login-csrf, feature/payment-webhook. Gibt es eine Issue-Nummer, füge sie hinzu: feature/142-pdf-export.
Commit-Disziplin
Ein Commit sollte eine einzige logische Änderung beschreiben. „Alles in einem Commit" und „ein eigener Commit für jede Zeile" sind die beiden zu vermeidenden Extreme. Eine gute Nachricht beantwortet das Warum statt des Was, denn das „Was" ist bereits im Diff sichtbar:
git add app/Http/Controllers/AuthController.php
git commit -m "fix: bei abgelaufener Session zum Login statt 419 weiterleiten"
Das Conventional-Commits-Format (feat:, fix:, chore:, docs:) ist sowohl lesbar als auch praktisch für die automatische Changelog-Erzeugung. Halte die erste Zeile bei 50–72 Zeichen und füge bei Bedarf nach einer Leerzeile Details hinzu. Vermeide es, unfertigen, nicht kompilierenden Code zu committen; brauchst du wirklich einen Zwischenstand, nutze git stash oder einen markierten „WIP"-Commit und räume ihn später mit git rebase auf.
Den Branch aktuell halten: merge oder rebase?
Während du an deinem Branch arbeitest, rückt der Hauptbranch vor. Es gibt zwei Wege, deinen Branch zu aktualisieren. Merge integriert die Änderungen aus main in deinen Branch und hinterlässt einen Merge-Commit; die Historie ist ehrlich, wirkt aber verschachtelt. Rebase spielt deine Commits neu ab, als wären sie auf dem neuesten main gestartet; die Historie bleibt flach und lesbar.
git switch feature/benutzer-login
git fetch origin
git rebase origin/main
Die praktische Regel: Rebase bedenkenlos, um die Historie eines lokalen Branches aufzuräumen, den du noch nicht geteilt hast. Aber rebase keinen Branch, den andere bereits gepullt haben, um ihn dann per Force zu pushen (--force) — das beschädigt die Historie deiner Mitarbeitenden. In diesem Fall ist --force-with-lease sicherer, denn es verweigert den Push, wenn sich seit dem zuletzt gesehenen Stand etwas geändert hat.
Der Pull Request: deine Änderung sichtbar gemacht
Ist der Branch bereit, pushe ihn ins Remote und öffne einen Pull Request (PR):
git push -u origin feature/benutzer-login
Der PR ist der Ort, an dem der Code vor dem Merge besprochen wird. Ein guter PR ist klein — Änderungen unter 400 Zeilen werden deutlich besser reviewt, weil der Reviewer das Ganze im Kopf behalten kann. Die Beschreibung sollte enthalten:
- Was sich änderte und warum: ein Satz Kontext reicht meist.
- Wie getestet wurde: ein Screenshot, eine Befehlsausgabe oder Testschritte.
- Einen Link zum zugehörigen Issue (z. B.
Closes #142).
Automatisierte Prüfungen (CI) — Tests, Linter, Build — sollten auf dem PR laufen. Merge nicht, bevor es grün ist. Das beseitigt das „Bei mir lief es"-Problem weitgehend.
Code-Review und Mergen
Review ist kein Tor; es ist geteilte Verantwortung. Der Reviewer jagt nicht nur Fehler — er fragt nach Benennung, Randfällen und ob eine einfachere Lösung möglich ist. Kommentare zielen auf das Problem, nicht auf die Person; „was passiert in diesem Fall?" hält die Zusammenarbeit gesünder als „warum hast du es so gemacht?".
Nach der Freigabe wählst du eine Merge-Strategie:
- Squash Merge: fasst alle Commits des Branches zu einem sauberen Commit zusammen. Die Haupthistorie bleibt lesbar; das ist der Standard für die meisten Teams.
- Merge Commit: erhält die vollständige Historie des Branches. Gut für große, bedeutungsvolle Commit-Folgen.
- Rebase Merge: fügt die Commits in flacher Form an main an, ohne Merge-Commit.
Lösche nach dem Merge den Branch — sowohl remote als auch lokal. Angehäufte tote Branches erschweren das Lesen des tatsächlichen Repository-Zustands.
git switch main
git pull --ff-only
git branch -d feature/benutzer-login
git push origin --delete feature/benutzer-login
Häufige Fragen
Ist es nie in Ordnung, direkt nach main zu pushen?
In einem kleinen Soloprojekt ist es völlig in Ordnung. Doch sobald mehr als eine Person beteiligt ist, mache den Hauptbranch geschützt und leite jede Änderung über einen PR. Das erzwingt sowohl Review als auch das CI-Sicherheitsnetz.
Soll ich merge oder rebase verwenden?
Beides ist richtig; es ist eine Teamentscheidung. Eine praktische Balance: rebase, um deinen lokalen Branch aktuell zu halten und Commits aufzuräumen, und squash merge, um den PR in main zu bringen. Force-rebase niemals einen geteilten Branch.
Wie groß sollte ein PR sein?
So klein wie möglich. Lass ihn eine einzige logische Aufgabe abdecken. Ist ein Feature groß, teile es in kleine PRs, die unabhängig mergen können; Review und Rollback werden so einfacher.
Tust du dich schwer, den Git-Ablauf deines Teams einzuspielen? Wenn du Hilfe bei Branch-Strategie, CI-Einrichtung und einer Code-Review-Kultur brauchst, melde dich — lass uns gemeinsam einen einfachen Workflow bauen, der zu deinem Projekt passt.