Über unsMediaKontaktImpressum
Fabian Deitelhoff 22. November 2016

Multiple Verzweigungen: Git Branching-Modelle im täglichen Einsatz

Git hat sich in den vergangenen Jahren zu einem äußerst beliebten System für die verteilte Versionsverwaltung entwickelt. Es gilt unter anderem als performant und mächtig. Gerade letztere Eigenschaft trägt allerdings dazu bei, dass insbesondere am Anfang Aufwand notwendig ist, um sich mit den Besonderheiten des Systems vertraut zu machen. Vor allem bei Branches bietet Git die Möglichkeit, in vielen Entwicklungs-Szenarien eingesetzt zu werden. Der Artikel wirft daher einen Blick auf die sogenannten Branching-Modelle und wie diese den Alltag von Softwareentwicklern bereichern können.

Der Name Git löst oftmals zwei sehr gegensätzliche Emotionen aus. Auf der einen Seite ist das Freude, denn die verteilte Versionsverwaltung ist äußerst mächtig. Git bietet viele Features an, die zudem größtenteils konfigurierbar sind. Somit besteht die Möglichkeit, dass sich Git in vielen Entwicklerszenarien einsetzen lässt, ohne dass diese Szenarien auf Biegen und Brechen angepasst werden müssen. Ein großer Pluspunkt von Git sind die kostengünstigen Branches. Was das bedeutet, wird im Verlauf des Artikels erklärt. So viel vorweg: Branches sind schnell erstellt sowie kostengünstig was Speicherplatz und Rechenzeit anbelangt. Dadurch sind sie ideale Kandidaten, um den Softwareentwicklungsprozess zu unterstützen.

Aus diesem Grund haben sich in den vergangenen Jahren zahlreiche Branching-Modelle oder Branching-Workflows für Git herauskristallisiert. Diese Modelle beziehungsweise Workflows dienen dazu, mithilfe von Branches Prozesse bei der Softwareentwicklung abzubilden. Branches werden in der Welt von Git so umfangreich und zahlreich eingesetzt, dass Git ohne Branches schwer vorstellbar ist.

Was ist Git?

Das Thema Versionskontrolle sollte in der Softwarebranche so unumkehrbar angekommen sein, dass hoffentlich niemand mehr in Frage stellt, ob diese Systeme tatsächlich notwendig sind. Die Diskussionen, welches System das Beste für den ins Auge gefassten Einsatzzweck ist, sind allerdings voll im Gange. Was auch gut so ist, da diese Dialoge dazu führen, über Lösungen nachzudenken.

Die erste Version von Git tauchte im April 2005 auf der Bildfläche auf. Entwickelt wird es von Linus Torvalds und vielen anderen als Open Source-Projekt unter der GNU GPLv2-Lizenz. Git ist eine Mischung aus lokalem und zentralisiertem Versionsverwaltungssystem. Technisch realisiert ist es daher als verteilte Versionsverwaltung. Jeder Computer auf dem ein Repository vorhanden ist, besitzt eine Versions-Datenbank, also eine vollständige Kopie des gesamten Repositories. So gut wie alle Operationen lassen sich somit lokal auf dem System ausführen. In der Praxis erprobt haben sich aber auch Remote-Repositories auf Servern, damit beispielsweise ein Projektteam darüber Versionsstände austauschen kann. Notwendig ist das in Git allerdings nicht, da sich auch lokale Computer Versionen ihrer lokalen Repositories hin- und herschicken können. Pflicht ist ein "zentrales Repository" auf einem zentralen System daher nicht.

Git ist schnell, nutzt reguläre Dateien als Speicherort für Informationen und sichert die Integrität aller Daten vollautomatisch. Unter Git ist es schwer, Operationen durchzuführen, die nicht mehr rückgängig gemacht werden können. Insbesondere dann nicht, wenn in regelmäßigen Abständen in ein entferntes Repository gepusht wird.

Git und Branches – Einfach unzertrennlich

Am Anfang des Artikels wurde schon angedeutet, dass Git ohne Branches schwer vorstellbar wäre. Dabei ist weniger die Tatsache interessant, dass Git überhaupt Branches mitbringt, denn das ist auch bei anderen verteilten sowie nicht verteilten Versionsverwaltungssystemen der Fall. Es ist die Art und Weise, wie Git mit Branches umgeht, wie diese implementiert sind und was semantisch mit diesen möglich ist.

Oftmals wird im Zusammenhang mit Git das Branching als "Killer-Feature" genannt, das Git von anderen Versionsverwaltungssystemen unterscheidet. Wer zum ersten Mal mit Branches bei Git arbeitet und dieses Feature nur von anderen Versionsverwaltungen her gewöhnt ist, wird die Performance und die Leichtfüßigkeit wahrnehmen, mit der Git Branching-Operationen ausführt. Branches anlegen, löschen und dergleichen, scheint fast ohne Verzögerung abzulaufen. Das gilt ebenso für den Wechsel zwischen Branches, eine Operation, die bei klassischen Versionsverwaltungen viel Aufwand im Dateisystem erfordert.
Diese technischen Vorteile von Branches in Git, führen schnell zu einem Umdenken. Wer mit Git arbeitet, wird dazu ermutigt, mit Branches zu arbeiten. Das betrifft sowohl die Anzahl der Branches in einem Repository, die bei Git in der Regel recht hoch ist, als auch die Häufigkeit von Branching- und Merging-Operationen. Diese können durchaus mehrmals am Tag stattfinden. Sich mit Git auseinanderzusetzen heißt daher auch immer, sich mit dem Branching und Merging zu beschäftigen. Ohne ist Git nicht mehr dieselbe Versionsverwaltung.

Im Gegensatz zu anderen Versionsverwaltungen, speichert Git die anfallenden Daten nicht als eine Abfolge von Änderungen beziehungsweise den Differenzen der verschiedenen Versionen. Git nutzt eine Serie von Schnappschüssen, um die Änderungsverfolgung zu realisieren. Pro Commit wird ein Commit-Objekt gespeichert, das einen Zeiger zu dem Schnappschuss mit den Objekten der Staging-Area darstellt. Zusätzlich zu Metadaten, dem Autor und einem Zeiger zum direkten Vorgänger des Commits.

Ein Branch in Git ist technisch als einfacher Zeiger auf so ein Commit realisiert. Mit dem ersten Commit in einem Repository, wird automatisch ein Branch mit Namen master erzeugt, der auf ebendiesen gerade erzeugten Commit zeigt. Mit jedem weiteren Commit wandert der Zeiger des Branches einfach weiter und zeigt immer auf den zuletzt erzeugten Commit.
Wird ein neuer Branch erzeugt, braucht Git aus technischer Sicht nur einen neuen Zeiger für diesen Branch erzeugen, der auf den Commit zeigt, auf dem gerade gearbeitet wird. Damit Git und wir wissen, auf welchem Branch wird gerade arbeiten, gibt es noch einen speziellen Zeiger mit Namen HEAD. Dieser Zeiger verweist auf den aktuellen Branch.

Diese genannten Konzepte sind es, die das Branching mit Git so spielend einfach machen. Aus technischer Sicht muss bei einem neuen Branch nur eine 41 Byte große Datei erzeugt werden. 40 Byte für die SHA-1 Prüfsumme des Commits, auf den der Branch verweist, plus ein Zeilenumbruch. Es ist nicht notwendig, ganze Verzeichnisstrukturen inklusive Dateien bei einem neuen Branch zu kopieren, was bei großen Repositories durchaus Minuten in Anspruch nehmen kann.

Warum Branching-Modelle?

Dass Git Branching auf die oben beschriebene Weise unterstützt, ist schon mal ein guter Anfang für eine längere berufliche Beziehung. Allerdings nützt die technische Unterstützung beziehungsweise das Vorhandensein eines Features kaum etwas, wenn es nicht im Entwickleralltag eingesetzt wird. Das gilt auch für das Branching. Was es braucht sind semantische Modelle und Workflows, um den Einsatz von Branches im Team zu ermöglichen und zu einem gewissen Grad auch zu rechtfertigen.

Ein Branching-Modell ist nichts anderes als ein Workflow, der erst durch die leichtfüßigen Branches möglich wird, die in Git realisiert sind. Bei diesen Workflows gilt die Regel, dass sie als Vorlage und grobe Richtung zu verstehen sind. Wir können uns Schritt für Schritt an diese Vorlagen halten oder Änderungen vornehmen. Dies ist jedem Entwickler beziehungsweise jedem Team selbst überlassen. Nur eins ist ganz besonders wichtig: Absprachen. Welcher Workflow letztendlich zum Einsatz kommt, spielt eine weniger wichtige Rolle. Viel wichtiger ist, dass überhaupt eine Art Workflow beim Branching vorhanden ist und dass sich das gesamte Team an diesen Workflow hält. Ansonsten ist Chaos vorprogrammiert.

Eine Übersicht von Branching-Modellen

Git macht uns praktisch keine Vorgaben darüber, wie ein Branching-Modell auszusehen hat. Einschränkungen gibt es natürlich von technischer Seite durch die Implementierung von Branches in Git, die auch ein darübergelegtes semantisches Modell nicht auflösen kann. Allerdings ist das Branching in Git immer noch eines der flexibelsten Systeme, wenn nicht sogar das flexibelste überhaupt.

Daher haben sich in den vergangenen Jahren zahlreiche Workflows herausgebildet, wie Branches nicht nur bei der täglichen Arbeit mit Git sinnvoll zum Einsatz kommen können, sondern sich auch in das Unternehmen beziehungsweise die Arbeitsweise von Teams integrieren. Im Folgenden gibt es daher einen kleinen Überblick über vorhandene Branching-Modelle, ohne Anspruch auf Vollständigkeit zu erheben. Anschließend greift der nachfolgende Abschnitt einen konkreten Branching-Workflow heraus, um diesen detaillierter zu beschreiben. Für eine genauere Analyse aller Workflows braucht es deutlich mehr als einen Artikel.

Die meisten Git Branching-Modelle unterscheiden verschiedene Arten von Branches. Technisch gesehen sind das immer noch normale Git Branches, die Semantik ist nur eine andere. Ganz allgemein lässt sich eine Unterteilung in langlaufende Branches (long-running) und Themen-Branches (topic) treffen [1]. Erstere gehören zu der Sorte von Branches, die eine sehr lange Laufzeit haben. Vielleicht sogar unbegrenzt beziehungsweise so lange, wie das Repository an sich besteht. Der Master-Branch ist ein recht anschauliches Beispiel. Er wird nicht gelöscht, sondern nur durch Commits angereichert. Themen-Branches beinhalten, wie der Name schon vermuten lässt, ein spezielles Thema. Zum Beispiel ein Feature oder eine Fehlerbehebung. Sobald die in diesen Branches gemachten Änderungen abgeschlossen sind, werden sie in andere Branches, zum Beispiel den Master-Branch, übernommen. Danach können die einzelnen Themen-Branches gelöscht werden, wenn das im Kontext sinnvoll erscheint. Oftmals nutzen Git Branching-Modelle eine Mischung aus beiden Branch-Arten.

Die einfachste Variante für einen Git Branching-Workflow ist fast schon kein wirklicher Branching-Workflow mehr. Der zentralisierte Workflow ist eine praktische Methode, um von eher klassischen Versionsverwaltungssystemen auf Git zu wechseln. Es gibt ein zentralisiertes Repository auf einem Server, wo alle Änderungen gesammelt werden. Jedes Teammitglied klont sich dieses Repository, um dann darin zu arbeiten. Änderungen werden direkt ins zentralisierte Repository gepusht beziehungsweise von dort auch wieder gepullt. Konflikte müssen dabei eventuell auch aufgelöst werden. In der Regel von dem Teammitglied, das beim Pushen von Git über Fehler informiert wird. Das zentralisierte Repository enthält – streng nach der Lehre – nur den Master-Branch. Bei diesem Workflow bleibt also nahezu alles so wie es ist, verglichen mit nicht verteilten Versionsverwaltungssystemen.

Der nächste Workflow in der Kurzvorstellung trägt den Namen Feature-Branch-(oder: Branch per Feature)-Workflow. Hier wird es jetzt etwas ernster, was den Einsatz von weiteren Branches betrifft. Die technischen und organisatorischen Rahmenbedingungen des zentralisierten Workflows werden beim Feature Branch-Workflow übernommen. Also ein zentrales Repository aus dem sich alle Teammitglieder bedienen. Allerdings werden die Änderungen der jeweiligen Mitglieder nicht mehr direkt in den lokalen Master-Branch eingepflegt und bei Fertigstellung in den Master-Branch des globalen Repositories übernommen, sondern es kommen Feature-Branches zum Einsatz. Das kann wörtlich übersetzt werden: also ein neuer Branch pro Feature. Diese Branches werden von den Teammitgliedern in den lokalen Kopien des zentralisierten Repositories erstellt. Das beschreibt sehr gut das Schlüsselkonzept hinter diesem Workflow: Die Entwicklung von neuen Features sollen isoliert in eigenen Branches statt dem Master-Branch stattfinden. Da Git keine technische Unterscheidung zwischen einem Master und einem beliebigen Feature Branch vornimmt, stehen auch bei den Feature-Branches alle Möglichkeiten von Git bereit, damit zu arbeiten. Ein weiterer Vorteil ist, dass ein Branch pro Feature die Möglichkeit für Pull Requests eröffnet. Ein Teammitglied kann einem anderen so ein Pull Requests schicken und damit den lokalen Feature-Branch verteilen, ohne den Master-Branch im zentralisierten Repository zu verändern, was das gesamte Team mitbekommen würde.

Der dritte Workflow im Bunde trägt den Namen Git-Flow. Dieser Workflow wird im nachfolgenden Abschnitt detaillierter beschrieben. Die Konzeption des Workflows wird Vincent Driessen [2] zugeschrieben, der den Workflow für das Unternehmen nvie [3] erstellt hat. Git-Flow ist strenger als der Feature-Branch-Workflow und gilt als besser geeignet für größere Projekte. Neue Konzepte sind, im Vergleich zum Feature-Branch-Workflow, nicht notwendig. Allerdings werden weitere long-running Branches genutzt, um die entstehenden Branches weiter aufzuteilen. Welche das konkret sind, wird im folgenden Abschnitt beschrieben.

Der Forking-Workflow beschreibt eine gänzlich andere Arbeitsweise, als die bisherigen Branching-Modelle. Anstatt einem einzigen zentralisierten Repository, das gibt es weiterhin, bekommt jedes Teammitglied ebenfalls ein eigenes zentralisiertes Repository. Das ist ein Fork, also eine 1:1-Kopie auf dem Server. Das Repository, von dem alle einen Fork erstellt haben, wäre per Konvention das offizielle, da Git so eine Unterscheidung technisch nicht vorgesehen hat. Dann müsste es noch einen Repository Maintainer geben, der auf das offizielle Repository aufpasst und dort die Änderungen der Entwickler einpflegt, die auf ihren Forks fleißig entwickelt haben. Das gelingt wieder über Pull Requests. Viele Open Source-Projekte arbeiten auf diese Weise. Alle die mitmachen haben einen Fork, auf dem sie werkeln können. Änderungen werden dann nach Abschluss über Pull Requests dem Maintainer oder einem Maintainer-Team des Projekts vorgeschlagen. Nach Begutachtung der Änderungen werden diese übernommen, abgelehnt oder es wird um Anpassungen gebeten. Wurden Änderungen eingepflegt, können die Teammitglieder diese über das offizielle Repository beziehen, um wieder auf dem aktuellen Stand zu sein.

Daneben gibt es zahlreiche weitere Branching-Modelle, die zum Beispiel von Unternehmen erdacht wurden und dort zum Einsatz kommen. Ein durchaus bekannter ist der GitHub-Flow vom Unternehmen GitHub. Dieser Workflow basiert auf Ideen des Git-Flow-Workflows, verändert diesen aber in einigen Teilen. GitHub selbst findet diesen so konzipierten Workflow um einiges einfacher als das Original Git-Flow. Ob das tatsächlich so ist beziehungsweise so empfunden wird, lässt sich schwer verallgemeinernd sagen. Hintergrund dieses Workflows ist, dass es einen Master-Branch gibt, der auslieferbare Versionen eines Produkts beinhaltet. Auf dem Stand des Master-Branches werden Feature-Branches erstellt, wenn eine neue Funktion entwickelt werden soll. Nach Abschluss der Arbeiten wird ein Pull Request erstellt, so dass weitere Personen über die Änderungen schauen können. Ist alles in Ordnung, wird der Branch in den Master-Branch übernommen und das Spiel beginnt von Neuem. So zumindest die Kurzfassung. Eine gute Übersicht bietet der Blogbeitrag zum Thema von Scott Chacon, der bei GitHub arbeitet [4].

Git-Flow im Fokus

Nun geht es konkreter um den bereits angesprochenen Git-Flow-Workflow. Ein Branching-Modell, so scheint es, dass aktuell recht häufig im Einsatz ist. Der Fokus liegt auf einer strengeren Branching-Politik mit zahlreichen long-running Branches für verschiedene Zwecke. Ausgerichtet ist der Workflow auf größere Projekte und rund um den Prozess beziehungsweise die Anforderungen eines Projekt-Releases.

Die langläufigen Branches werden als Historie für den Projektverlauf genutzt. Davon gibt es zumindest schon mal den Master- und den Develop-Branch. Ersterer enthält die offizielle Release-Historie. Bei jedem Release müssen die Änderungen also in den Master-Branch wandern. Daher ist es auch häufiger Ritus, bei jedem Release die Commits im Master-Branch durch Tags mit Versionsnummer zu versehen. Der Develop-Branch dient als Integrationsstelle der Änderungen, die durch die jeweiligen Teammitglieder im Laufe der Zeit durchgeführt werden. Branches wie Master oder Develop werden auch häufig als Environment-Branches bezeichnet. Sie spiegeln nicht nur einen gewissen Stand im Release-Management einer in Entwicklung befindlichen Anwendung wider, sondern eben auch einen gewissen Stand einer Umgebung. Eine eingeworfene Notiz am Rande: Es ist durchaus denkbar, einen Branch Live zu nennen, um dort aktuell laufende Stände zu speichern. Nicht nur ausgelieferte, sondern vielleicht direkt durch ein Continuous Delivery-System auf einen Server aufgespielte Versionsstände. Ob das sinnvoll oder eher gefährlich ist, hängt wieder von Kontext ab. Git steht uns da aber nicht im Weg.

Diese Änderungen finden in den bereits bekannten Feature-Branches statt. Wird die Entwicklung eines Features begonnen, ist der Startpunkt allerdings nicht der Master-Branch, sondern der Develop-Branch. Dieser dient als Ausgangspunkt für die neuen Feature-Branches, die mit Leben gefüllt werden. Ist der Zeitpunkt erreicht, wo ein Feature abgeschlossen ist, werden die Änderungen des entsprechenden Branches zurück in Develop überführt. Hier ist dann die Stelle, wo es zu potentiellen Problemen kommen kann, da alle anderen Teammitglieder ebenso verfahren. Es kann also zu Merge-Konflikten führen, wenn der Develop-Branch mittlerweile durch andere eingepflegte Feature-Branches abweicht. Dies ist im Prinzip die Beschreibung des Feature-Branch-Workflows, wenn wir nur die Feature-Branches und den Develop-Branch betrachten. Das ist auch korrekt. Mit der großen Ausnahme oder Einschränkung, dass Feature-Branches niemals direkt mit dem Master interagieren sollen. Das war beim Feature-Branch-Workflow anders. Den bisherigen Stand verdeutlicht Abb.1.

Ab jetzt ist es möglich, zu einem gewissen Zeitpunkt – zum Beispiel, weil alle (oder ausreichend) Features umgesetzt worden sind – den Develop-Branch in den Master-Branch zu mergen. Dadurch wird gekennzeichnet, dass es sich um eine neue Produktversion handelt, die beispielsweise ausgeliefert werden kann. Eine Abweichung, die der Git-Flow-Workflow auch so strikt vorsieht, ist der Release-Branch. In den Release-Branch werden die Features eingepflegt, wenn es zu einer neuen Version kommen soll. Der Release-Branch enthält somit einen Stand des Features und ist vom Develop-Branch abgekoppelt. In den Release-Branch sollen dann nur noch Änderungen in Form von Bugfixes oder ähnlichem eingepflegt werden. Wird ein neuer Release-Branch erzeugt, kennzeichnet das einen neuen Release-Zyklus. Grundsätzlich ist es dann möglich, dass ein Teil des Teams an neuen Features arbeitet und ein anderer Teil Fehler im Release-Branch behebt. Ist alles soweit erledigt, kann der Release-Branch in den Master-Branch eingepflegt und mit einer Versionsnummer als Tag versehen werden. Wichtig ist, dass Änderungen im Release-Branch auch zurück in den Develop-Branch überführt werden müssen, da ansonsten neue Features, die vom Develop-Branch starten, nichts davon mitbekommen. Ob diese Vorgehensweise zum eigenen Unternehmen passt oder ob eigene Release-Branches als zu viel Aufwand empfunden werden, muss jeder für sich selbst entscheiden. In der Praxis sind beide Workflows anzutreffen. Sowohl streng nach dem Git-Flow-Workflow mit Release-Branch als auch aufgeweichter ohne diese Trennung. Abb.2 zeigt die Änderungen der Workflows mit den besprochenen Release-Branches.

Zu guter Letzt kommt eine weitere Art von Branches ins Spiel. Die sogenannten Maintenance-Branches sind für Wartungszwecke gedacht. Das bedeutet konkret, ein Hotfix-Branch aus einem Stand des Master-Branch erzeugt wird, um dort zum Beispiel Patches oder sonstige Fehlerbehebungen einzuspielen. Damit ist ein Hotfix-Branch der einzige Branch, der direkt aus dem Master-Branch erzeugt wird. Nachdem die Veränderungen durchgeführt sind, müssen die Änderungen natürlich auch wieder in den Master-Branch zurückgeführt werden. Allerdings nicht nur dorthin, auch der aktuelle Develop-Branch benötigt diese Änderungen. Oder, wenn es gerade einen aktuellen Release-Branch gibt, dort hinein. Auf diese Weise ist es möglich, an Patches zu arbeiten, ohne das restliche Team an der Arbeit zu hindern. Abb.3 zeigt den letzten Stand des Workflows mit allen Arten von Branches, die angesprochen wurden. Es muss allerdings klar sein, dass eine weitere Art von Branch die Komplexität des Workflows weiter ansteigen lässt. Und mit der Komplexität steigt in der Regel auch die Fehlerwahrscheinlichkeit. Wie potenzielle Fehlerquellen ausgemerzt werden können, zeigt der nächste Abschnitt.

Alle gezeigten Beispiele für Workflows sind eben auch nur das: Beispiele. Vorschläge, wie mit den technischen Möglichkeiten von Git umgegangen werden kann. Die Workflows lassen sich auf beliebige Arten verändern. Nicht alle Workflows passen für alle Unternehmen. Wer mit wenigen Personen eine kleine Anwendung schreibt, braucht vielleicht nicht alle Arten von Branches eines Git-Flow-Workflows. Bei der Auswahl eines Workflows muss daher auch etwas Zeit darauf verwendet werden, den ein oder anderen Workflow anhand von Beispielen durchzuspielen, um damit warm zu werden. Ein paar Tipps dazu verrät der Abschnitt zur Auswahl einer geeigneten Strategie.

Naming is hard

Die Namensgebung von Dingen in der Informatik ist eh schon ein Thema für sich. In diesem Fall ist die Benennung von Branches gemeint. Einige Namen wie Master und Develop stehen fest beziehungsweise erscheinen recht eindeutig und sinnvoll. Aber wie ist das bei Feature-Branches? Die Namensgebung steht noch etwas in der Luft.

Grundsätzlich ist jeder Name erlaubt, solange er nicht mit bereits existierenden Branches wie Master oder ähnlichem kollidiert. Das wäre eine unkluge Wahl. Hier sind einige Anregungen, wie Feature-Branches benannt werden können.

Am Anfang können bestimmte Wörter zur Gruppierung herangezogen werden. Ganz plump im Sinne von gruppe1/…, gruppe2/… und so weiter. Zum Beispiel um bestimmte Features in Gruppen einzuteilen und diese schneller wiederzufinden. Oftmals bieten Tools es auch an, eine Gruppe zum Beispiel Feature zu nennen, um so alle Feature-Branches direkt aufzufinden. Dazu mehr im Bereich zur Toolunterstützung. Zahlen sind allerdings keine gute Idee. Gerade dann nicht, wenn die Kommandozeile mit ins Spiel kommt. Beim Erweitern von Kommandos mit der Tag-Taste könnte Git auf die Idee kommen, nach SHA-1 Nummer von Commits zu suchen und im schlimmsten Fall auch welche finden. Dann wäre sich Git unsicher, ob wir Branches oder Commits meinen.

Einzelne Teilbereiche von Branch-Namen können mit Schrägstrichen getrennt werden – wie das oben bei den Gruppen schon der Fall war. So wird deutlich, dass der nachfolgende Teil zwar zum Branch-Namen gehört, aber nicht Teil eines längeren Namens ist. Teile eines längeren Namens können durch Bindestriche voneinander getrennt beziehungsweise die Zugehörigkeit angezeigt werden. Zum Beispiel beim Feature gruppe3/bluetooth-connection. Das Feature gehört zur Gruppe drei und behandelt die Verbindung über Bluetooth.

Bei der Länge von Branch-Namen streiten sich die Geister. Auf der einen Seite sind längere beschreibende Namen besser bei der Übersicht, wenn eine Liste von Branches durchgegangen werden muss. Diese längeren Namen können aber schnell im Weg sein, wenn es zum Beispiel um eine Log-Datei geht. Dann stören die zusätzlichen Zeichen schnell wieder.

Das sollen nur einige Tipps darstellen, die berücksichtigt werden können. Viel wichtiger ist es, dass es Regeln im Team oder Unternehmen gibt, sodass jedes Teammitglied mindestens ähnliche, am besten identische Schreibweisen für Branches nutzt. Git selbst legt uns hier keine Steine in den Weg.

Toolunterstützung

Für die Unterstützung bei der täglichen Arbeit mit Git und Git-Branching-Modellen gibt es zahlreiche grafische Tools. Die Kommandozeile steht ohnehin die ganze Zeit zur Verfügung, aber es kann durchaus Sinn ergeben, ein grafisches Werkzeug zu nutzen.
Ein Vertreter dieser Art ist GitKraken. Eine auf dem Electron Framework basierende Anwendung, die viele Möglichkeiten von Git über eine grafische Oberfläche zur Verfügung stellt. Abb.4 zeigt die vollständige Oberfläche verkleinert dargestellt. Erfreulicherweise unterstützt GitKraken ein Branching-Modell. Konkret ist Git-Flow integriert, was in den Optionen eines Repositories aktiviert werden kann, wie Abb.5 zeigt. Die vorgeschlagenen Namen zeigen bereits das Schema von Git-Flow. Die oben angesprochenen Gruppen von Branch-Namen sind für die Feature-, Release- und Hotfix-Branches bereits umgesetzt.

Nachdem auf diese Weise ein Repository konfiguriert wurde, was nur bedeutet, dass GitKraken zu einem Repository einige Metadaten speichert, steht Git-Flow auch über die Oberfläche zur Verfügung. Abb.6 zeigt den neu hinzugekommenen Menüeintrag auf der rechten Seite. Die linke Seite zeigt die Optionen, die dadurch zur Verfügung stehen. Über diese Menüeinträge kann jetzt zum Beispiel ein Feature gestartet und nach Abschluss aller Implementierungen auch beendet werden. GitKraken kümmert sich dann darum, dass ordnungsgemäße Branches erzeugt und wieder zurück gemergt werden. Die Namen der Branches werden per Dialog abgefragt. Genauso wie die Quelle für einen neuen Feature-Branch. Beim Abschließen eines Features besteht zudem die Möglichkeit, den lokalen Feature-Branch zu löschen, damit sich über die Zeit nicht ein riesiger Haufen an Branches anhäuft.

Auswahl einer geeigneten Strategie

Git hat sich in Windeseile nicht nur zu einer ernstzunehmenden Alternative zu anderen Versionsverwaltungssystemen entwickelt. Es steht mittlerweile ziemlich weit oben, einige würden sagen an der Spitze, wenn es um die Auswahl einer Versionsverwaltung geht. Es ist ein fantastisches Tool und darf sicherlich ohne zu zögern als Industriestandard bezeichnet werden.

Dazu haben auch die angesprochenen mehr oder weniger standardisierten Workflows beitragen. Sie vermitteln Sicherheit. Sowohl technisch gesehen, da etliche Features von Git auf eine sinnvolle und hoffentlich nachvollziehbare Art und Weise eingebunden sind. Aber auch aus organisatorischer Sicht, da viele am Anfang oft nicht wissen, wie sie mit Git umgehen sollen.

Meine Empfehlung ist, mit einem einfachen Workflow anzufangen. Im Zweifel mit dem zentralisierten Workflow, der sich kaum von klassischen Workflows von zentralisierten Versionsverwaltungssystemen wie Subversion unterscheidet. Anschließend ergibt entweder ein vereinfachter Git-Flow-Workflow – zum Beispiel ohne Release- und Maintenance-Branches – oder der GitHub-Workflow Sinn. Vielleicht auch schon direkt vom Start aus, falls Git schon etwas bekannt ist.

Diese beiden Workflows bieten die Vorteile von Feature-Branches, nutzen damit die Branching-Möglichkeiten von Git sehr zahlreich, sind aber dennoch nicht ganz so komplex, um am Anfang zu sehr zu überfordern. Zusammen mit einem Tool – wie zum Beispiel GitKraken – kann so der Einstieg gelingen. Sowohl in ein Branching-Workflow wie auch in Git an sich, falls das noch nicht bekannt ist. Empfohlen ist es allerdings dennoch, sich mit der Kommandozeile von Git auseinanderzusetzen. Eine sehr empfehlenswerte Quelle dafür ist das interaktive Online-Tutorial mit Namen Learn Git-Branching [5]. Abb.7 zeigt dazu einen Ausschnitt des Browserfensters. Das Tutorial erlaubt die Eingabe von Git-Kommandos, deren Auswirkungen direkt angezeigt werden. Auf diese Weise können Befehle ausprobiert werden, die in realen Repositories bei nicht korrekter Anwendung evtl. unschöne Auswirkungen haben.

Eine Sache noch zur Komplexität. Oft wird behauptet, Git sei einfach. Prinzipiell ist es das auch. Allerdings erst, wenn der Einstieg gelungen ist, beziehungsweise, wenn einem selbst klargeworden ist, wie Git tickt. Am Anfang kann Git ganz schön hart sein. Dahinter steckt eine gänzlich andere Philosophie, die durch den Entwickler Linus Torvalds geprägt wurde. Viele einzelne Tools, die spezielle Aufgaben übernehmen. Ein Prinzip, das auch von Linux bekannt ist. Die anfänglichen Schwierigkeiten und Mühen lohnen sich aber, wenn der Knoten geplatzt ist.

Fazit

Git ist über die Jahre zum Platzhirsch im Bereich der verteilten Versionsverwaltungssysteme aufgestiegen. Scheinbar mühelos werden Alternativen wie Subversion oder Mercurial verdrängt beziehungsweise haben es schwierig, gegen Git zu bestehen.

Der Anfang kann hart sein. Die Mühen lohnen sich aber. Spätestens beim Einsatz von Branching-Modellen wird deutlich, wie viel mit Git, im Speziellen beim Thema Branching, möglich ist. Git-Flow ermöglicht auch das technische Management von größeren Projekten in einem Repository. Wem dieser Workflow zu starr ist oder zu komplex erscheint, ist mit weniger stringenten Workflows wie der Feature-Branch-Lösung oder einem einfachen zentralisierten Workflow ebenfalls gut bedient. Die Hauptsache ist, ein Workflow wird innerhalb des Teams beziehungsweise innerhalb des Unternehmens konsequent angewandt.

Quellen
  1. Weitere Erklärungen zu verschiedenen Branch-Arten in Git
  2. Details zum Git-Flow-Workflow
  3. Unternehmenswebseite zu nvie
  4. Blogbeitrag von Scott Chacon zu GitHub-Flow
  5. Das Online-Tutorial Learn Git-Branching

Autor

Fabian Deitelhoff

Fabian Deitelhoff lebt und arbeitet in Dortmund, der Metropole des Ruhrgebiets. Er studiert derzeit den Masterstudiengang Informatik mit dem Schwerpunkt Biomedizinische Informatik an der Hochschule Bonn-Rhein-Sieg in Sankt...
>> Weiterlesen
botMessage_toctoc_comments_9210