Gitflow-Workflow
Lerne den Gitflow-Workflow mit main-, develop-, feature-, release- und hotfix-Branches und wann die Struktur hilft.
Überblick
Gitflow ist ein strukturiertes Branching-Modell, das Vincent Driessen 2010 populär machte und für Projekte mit geplanten, versionierten Releases konzipiert wurde. Anstelle eines einzelnen Integrations-Branches nutzt es zwei langlebige Branches sowie drei Arten von unterstützenden Branches, jeder mit einem definierten Zweck. Die Struktur macht das Release-Management explizit – auf Kosten von mehr Formalität.
Die zwei langlebigen Branches
Diese zwei Branches bestehen für die gesamte Lebensdauer des Projekts – sie werden niemals gelöscht.
- main enthält produktionsbereiten Code. Jeder Commit auf
mainentspricht einer veröffentlichten Version und ist in der Regel getaggt (beispielsweisev1.4.0). Wer genau wissen möchte, was in der Produktion läuft, checktmainaus. - develop ist der Integrations-Branch, in dem fertige Features zwischen den Releases gesammelt werden. Er enthält stets die neuesten abgelieferten Änderungen für das nächste Release, wobei diese Änderungen nicht unbedingt bereits stabil sind.
Da beide Branches permanent sind, setzt sich die Beziehung zwischen ihnen nie zurück: develop ist immer um alles, was noch nicht veröffentlicht wurde, „voraus" gegenüber main.
Die drei unterstützenden Branches
Die unterstützenden Branches sind kurzlebig. Jeder wird für einen bestimmten Zweck erstellt, nach dessen Erfüllung gemergt und anschließend gelöscht. Namenskonventionen (feature/, release/, hotfix/) machen ihre Rolle in der Ausgabe von git branch sofort erkennbar.
Feature-Branches
Feature-Branches werden von develop abgezweigt und wieder in develop gemergt. Sie beinhalten die Arbeit für kommende Funktionalität und interagieren nie direkt mit main – ein einzelnes Feature wird nie allein released; es wird als Teil des nächsten versionierten Releases ausgeliefert.
git switch develop
git switch -c feature/search # create + check out feature/search
# ...work and commit...
git switch develop
git merge feature/search # fold the feature into develop
git branch -d feature/search # delete it once mergedgit switch -c <name> erstellt den Branch aus dem aktuellen Branch und checkt ihn in einem Schritt aus – es ist das moderne Äquivalent zu git checkout -b. Weitere Informationen zum vollständigen Befehl findest du unter Git switch. Kurzlebige Feature-Branches begrenzen, wie weit sie von develop abweichen, was Merge-Konflikte klein hält.
Release-Branches
Release-Branches werden von develop abgezweigt, wenn dieser für ein Release feature-vollständig ist. Sie dienen ausschließlich der abschließenden Politur – Versionserhöhungen, Release-Notes und letzte Bugfixes – während develop für die Features des nächsten Zyklus offen bleibt.
Wenn das Release bereit ist, wird der Branch an beide Stellen gemergt:
- in
main, wo er mit der Versionsnummer getaggt wird; und - zurück in
develop, damit etwaige Stabilitätskorrekturen aus dem Release-Branch nicht verloren gehen.
git switch -c release/1.4.0 develop
# ...bump version, fix last bugs, write release notes...
git switch main
git merge --no-ff release/1.4.0 # record an explicit merge commit
git tag -a v1.4.0 -m "Release 1.4.0"
git switch develop
git merge --no-ff release/1.4.0 # carry fixes back into develop
git branch -d release/1.4.0--no-ff (kein Fast-forward) zwingt Git, einen Merge-Commit zu erstellen, selbst wenn ein Fast-forward möglich wäre, sodass das Release als einzelner, sichtbarer Punkt in der Historie erhalten bleibt, anstatt flachgedrückt zu werden.
Hotfix-Branches
Hotfix-Branches werden von main abgezweigt, um einen Produktionsfehler dringend zu beheben – ohne auf die Fertigstellung der aktuellen develop-Arbeit warten zu müssen. Wie Release-Branches werden sie in beide Stellen gemergt: in main (getaggt mit einer erhöhten Patch-Version) und in develop, damit der Fix auch in zukünftigen Releases vorhanden ist.
git switch -c hotfix/1.4.1 main
# ...fix the bug and commit...
git switch main
git merge --no-ff hotfix/1.4.1
git tag -a v1.4.1 -m "Hotfix 1.4.1"
git switch develop
git merge --no-ff hotfix/1.4.1 # don't reintroduce the bug later
git branch -d hotfix/1.4.1Den zweiten Merge – zurück in develop – zu vergessen, ist der klassische Gitflow-Fehler: Der Bug taucht im nächsten Release wieder auf, weil der Fix nur in main gelandet ist.
Wann man Gitflow einsetzt
Gitflow glänzt, wenn man eigenständige, versionierte Releases ausliefert – Desktop-Apps, Bibliotheken, mobile Apps mit App-Store-Prüfung oder alles, das Versionsnummern pflegt und gelegentliche Notfall-Patches benötigt. Die expliziten Release- und Hotfix-Branches bieten einen klaren Ort zum Stabilisieren und zur Behebung von Produktionsproblemen, ohne die laufende Entwicklung zu stören. Die Notwendigkeit, mehrere veröffentlichte Versionen gleichzeitig zu unterstützen, ist das stärkste Signal dafür, dass sich Gitflows Struktur auszahlt.
Ein vollständiger Release-Zyklus auf einen Blick
Alle Teile zusammengesetzt bewegt sich eine Version folgendermaßen durch die Branches:
- Entwickler schneiden
feature/*-Branches vondevelopab, bauen und mergen jeden wieder indevelop. - Wenn
developgenug für ein Release enthält, wird einrelease/x.y.0-Branch für die abschließende Stabilisierung abgezweigt. - Der Release-Branch wird in
maingemergt, mitvx.y.0getaggt und zurück indevelopgemergt. - Wenn die Produktion ausfällt, zweigt ein
hotfix/x.y.zvonmainab, wird getaggt und in beide –mainunddevelop– gemergt.
main schreitet daher nur durch Release- und Hotfix-Merges voran, und jeder Commit darauf ist eine auslieferbare, getaggte Version.
Die Kompromisse
Diese Struktur ist auch Gitflows Schwäche. Die vielen Branch-Typen erzeugen Overhead, und der langlebige develop-Branch kann weit von main abdriften, was Merges schmerzhaft macht. Langlebige Branches begünstigen große, seltene Integrationen – das Gegenteil von dem, was Continuous Delivery anstrebt. Teams, die viele Male täglich ausliefern, empfinden Gitflow meist als zu schwer und bevorzugen den einfacheren Feature-Branch- oder Trunk-basierten Ansatz, bei dem die Arbeit kontinuierlich in einen einzigen Branch integriert wird. Wähle Gitflow, wenn Release-Kadenz und parallele Versionsunterstützung – und nicht reine Deploy-Geschwindigkeit – deine Prioritäten sind.
Vergleiche es mit den Alternativen, bevor du dich festlegst: dem Forking-Workflow für Open-Source-Beiträge und einfachen Feature-Branches für die meisten Web-Apps, die aus einer einzigen Linie deployen.