Blog
dranbleiben!
Marcelo Emmerich

Warum git-flow hakt

Git ist heutzutage als de-facto Standard für Source Code Management kaum noch wegzudenken. Es existieren exzellente Produkte, die die Arbeit mit git vereinfachen, allen voran Github, Bitbucket und Gitlab. Nun stellt git erst einmal "nur" das Werkzeug zur Verfügung. Um damit professionell zu arbeiten, benötigt man auch einen Prozess, der in die Entwicklung hineingreift und bis zum Continuous Integration und Continuous Deployment geht. Eines der bekanntesten git Workflows ist git-flow. Den Grundlegenden Ablauf von git-flow ist hier zu sehen: Git-Model Man kann anhand des Diagrammes schon sehen, dass ein Szenario mit vielen Entwicklern, Branches, Versionen und Releases schnell komplex werden kann. Trotzdem ist git-flow ziemlich populär, da es eine gewisse Ordnung propagiert und Richtlinien vorgibt. Das ist zumindest die Theorie. In der Praxis macht sich seit geraumer Zeit Kritik breit, die meistens folgendes bemängelt:

  • Merge Konflikte.
  • Feature-Trennung
  • Probleme bei der Release-Planung

Ich werde im Einzelnen auf diese Punkte eingehen. Vorab möchte ich aber festhalten, dass das eigentliche Problem die langlebigen Branches sind. Langlebige Branches entstehen wenn die Arbeit, die in einem Branch erledigt werden soll viel zu umfangreich dimensioniert wurde, so dass der Branch zu lange existiert. Daraus resultieren die o.g. Probleme. Und git-flow neigt dazu, eben diese langlebigen Branches zu produzieren. Auch auf die Gefahr hin, dass ich wieder ins SCRUM-bashing verfalle, aber SCRUM und an SCRUM orienterte Tools erhöhen die Wahrscheinlichkeit von langlebigen Branches. Hier ein Beispiel aus der Praxis.

In Projekt XY wurde der (hervorrangende) Atlassian Stack (Jira, Bitbucket und Confluence) und (das weniger hervorragende) SCRUM eingesetzt. Sprich es gab User Stories, die es umzusetzen galt. Diese wurden im Jira verwaltet. Wenn also ein Entwickler eine User Story umsetzen sollte, wurde der Status der Story im Jira verändert (bspw. von "Ready for Dev" nach "in development"). Nun bietet Jira ein praktisches Feature. Man kann direkt aus der Story heraus ein Branch anlegen, der sich an den Namen der Story anlehnt. So wurde es gehandhabt, und so entstanden etliche langlebige Branches, weil die Entwickler nur in diesen Branch committed haben, bis die Story fertig war. Erst dann wurde gemerged.

Und dann traten die o.g. Problemen auf, auf die ich wie versprochen nun im Detail eingehe:

Merge Konflikte

Das ist glaube ich offensichtlich. Wenn es viele, langlebige Branches gibt, die unabhängig voneinander unterschiedliche Stände haben, und evtl. den gleichen Code verändern, wird es merge Probleme geben. Diese wachsen in Anzahl und Komplexität mit der Anzahl der am gleichen Code arbeitenden Entwickler, und können oft nicht automatisch aufgelöst werden. Das kosten Zeit und Nerven.

Feature-Trennung

Vielleicht kennt das der Eine oder Andere. Der PO fordert unvermittelt ein Release, der aus Business-Gründen Feature XY beinhalten muss. git-flow kennt da den Hotfix als Antwort. Was aber, wenn es Abhängigkeiten zu anderen, langlebigen Branches gibt? Das aufzulösen kann mitunter extrem aufwendig werden.

Probleme bei der Release-Planung

Die o.g. Punkte führen zum dritten und letzten Punkt. Es ist kaum möglich, den Merge-Aufwand für ein bestimmtes Release abzuschätzen. Da jeder Entwickler seit Tagen oder sogar Wochen nur in seinem langlebigen Branch arbeitet, kann keiner sagen, wie groß der Unterschied zwischen dem eigenen Code und der der anderen ist.

Trunk Based Development

Eine Möglichkeit, diese Probleme zu umgehen ist Trunk Based Development. Um die Definition zu bemühen, ist Trunk Based Development:

A source-control branching model, where developers collaborate on code in a single branch called ‘trunk’, resist any pressure to create other long-lived development branches by employing documented techniques, avoid merge hell, do not break the build, and live happily ever after.

Hier das entsprechende Bild dazu: trunk based dev

In der git Welt würde man statt trunk eher master branch sagen. Ändert aber nichts an der Idee. Amüsant find ich allerdings die Tatsache, dass trunk ein Begriff aus dem alt ehrwürdigem Source Code Management Werkzeug Subversion ist. Amüsant deswegen, weil heutzutage viele Entwickler git für so überlegen halten, dass SVN nur noch mit Mitleid betrachtet wird.

Aber das nur am Rande. Warum ist trunk based dev also besser als git-flow? Hier einige der Gründe:

  • Es wird immer nur vom trunk gebrancht
  • die Branches sind kurzlebig, < 1 Tag
  • es gibt insgesamt weniger Branches
  • es wird daher auch mehrfach am Tag gebaut

Vor allem der letzte Punkt ist hier von großer Bedeutung. Um es hier ganz deutlich zu sagen, wer nicht mindestens täglich einen release-tauglichen Build erzeugt praktiziert kein CI!!. CI ist nicht die Verwendung eines oder mehrerer Tools. Wir machen nicht CI weil wir Jenkins im Einsatz haben. Wir machen CI weil wir mehrmals täglich release-taugliche Builds durch das ständige Mergen in den trunk durch unsere CI pipelines jagen, inklusive automatisierter Tests. Alles andere ist ein Antipattern, bekannt unter dem Namen CI Theater.

Wir sehen also, dass die negativen Implikationen einer ohne Reflexion eingeführten Methode recht weitreichend sein können. Es lohnt sich, den eigenen Prozess rund um git und CI auf den Prüfstand zu stellen und ggf. trunk based development in Betracht zu ziehen.

none
Conventic Icon
Standort Bonn
Burgstraße 69
53177 Bonn
Deutschland
+49 228 76 37 69 70
Standort Braunschweig
Westbahnhof 11
38118 Braunschweig
Deutschland
+49 228 76 37 69 70
Wir sind Mitglied bei
Grouplink Icon
Newsletter abonnieren
Impressum, Haftungsausschluss, Datenschutzerklärung und
© 2024 conventic GmbH · Alle Rechte vorbehalten.