Das Branching-Modell Git-Flow
Während das Erstellen mehrerer Branches (zu Deutsch Zweige) bei Versionsverwaltungssystemen wie SVN (=Subversion – ist eine freie Software zur zentralen Versinsverwaltung von Dateien und Verzeichnissen) als fortgeschrittenes Feature gilt, so ist es eine Grundlage bei der Verwendung von git. Gerade für Neueinsteiger kann dieses Feature sehr verwirrend sein. Neben der Frage, wie man Branches nutzt, stellt sich die noch wichtigere Frage, wie man Branches sinnvoll einsetzt. Vincent Driessen stellte 2010 ein Branching-Modell vor, welches eben diese Frage klärt und als Git-Flow bekannt wurde.
Git-Flow
Neben Driessens Branching-Modell bezeichnet Git-Flow auch eine Erweiterung für git, welche die Arbeit mit git und dem Branching-Modell vereinfacht, indem Gruppen von aufeinanderfolgenden Befehlen zu einzelnen Befehlen zusammengefasst werden. Man kann aber auch ohne die git Erweiterung das Git-Flow Branching-Modell verwenden. Das Branching-Modell gibt vor, welche Branches existieren müssen und wie diese einzusetzen sind.
Im Mittelpunkt des Modells steht der sogenannte „develop“ Branch, der den aktuellen Stand der Entwicklung abbildet. Neben dem „develop“ Branch ist auch der „master“ Branch von zentraler Bedeutung, dieser repräsentiert fertige Produktversionen. Diese beiden Branches sind die einzigen, die beständig sind - also nicht wieder gelöscht werden, nachdem sie ihren Zweck erfüllt haben.
Features
Kleine Features können direkt am „develop“ Branch entwickelt werden, während größere Features in eigenen Feature Branches auszulagern sind. Von diesen kann es eine beliebige Menge geben, sie müssen aus dem „develop“ Branch erzeugt und auch wieder in diesen zurückgeführt werden. Beim Zurückführen eines Feature Branches in den „develop“ Branch ist darauf zu achten, dass dieser Branch in der Historie sichtbar bleibt, selbst wenn es in der Zwischenzeit keine anderen Änderungen auf dem „develop“ Branch gab. Das ist nützlich, um später einzelne Einträge, die zu einem Feature gehören, leichter identifizieren zu können. Aus dem Grund sollte hier kein „rebase“ verwendet werden und bei einem „merge“ sollte die Option „--no-ff“ („No fast forward“) verwendet werden.
Release
Soll ein Release vorbereitet werden, so wird aus dem „develop“ Branch heraus ein „release“ Branch erstellt, wobei dieser Branch immer noch einen Suffix mit der Versionsnummer im Namen erhält (z. B. „release-1.2“). Auf diesem Branch sollten nur noch Bugfixes vorgenommen werden, sowie versionsspezifische Änderungen (z. B. das Setzen der Versionsnummer im Code). Ist die Version bereit zur Veröffentlichung, so wird der „release“ Branch auf den „master“ Branch geführt, die Version wird dort außerdem getaggt. Der „release“ Branch wird zudem auch wieder auf den „develop“ Branch zurückgeführt, um eventuelle Bugfixes in spätere Versionen einzubringen, und anschließend wird er gelöscht.
Tritt in einer veröffentlichten Version (eine Version am „master“ Branch) ein kritischer Fehler auf, so kann aus dem „master“ Branch ein „hotfix“ Branch erstellt werden. Dieser erhält ebenfalls die neue Versionsnummer als Suffix im Namen (z. B. hotfix-1.2.1). Ist der Hotfix fertig, wird er (genau wie ein „release“ Branch) auf den „master“ Branch zurückgeführt, wo die Version getaggt wird. Um den Hotfix in die fortlaufende Entwicklung einzubringen, wird der „hotfix“ Branch in den „develov“ Branch geführt. Hier gibt es jedoch eine Ausnahme: Wenn gerade ein „release“ Branch existiert, wird der „hotfix“ Branch in den „release“ Branch geführt und nicht in den „develop“ Branch. Die Änderungen gelangen dann über den „release“ Branch wieder in den „develop“ Branch. Anschließend wird der „hotfix“ Branch gelöscht.
Da viele dieser beschriebenen Schritte mehrere git Operationen wie „checkout“, „merge“, „branch“ und „push“ benötigen, gibt es die Git-Flow Erweiterung für git, welche die häufigsten Schritte zu einzelnen „git flow“ Befehlen zusammenfasst. Auch Programme wie SourceTree haben die Git-Flow Funktionen bereits integriert.
Fazit
Das Branching-Modell Git-Flow bringt automatisch eine einheitliche Struktur in jedes Projekt, was vor allem dann von Vorteil ist, wenn viele Entwickler gleichzeitig an einem Projekt arbeiten. Durch die parallel laufenden Branches können gleichzeitig mehrere Features entwickelt, ein Release vorbereitet und Hotfixes durchgeführt werden. Damit eignet sich das Modell auch hervorragend für größere Projekte.