Verbesserter Git-Flow erklärt

Veröffentlicht: 2022-03-11

Mit Git unbeabsichtigt Schaden anzurichten, kann allzu einfach sein. Die beste Art, Git zu verwenden, wird jedoch immer umstritten sein.

Das liegt daran, dass Git selbst nur grundlegende Verzweigungsoperationen detailliert beschreibt, wodurch seine Verwendungsmuster – dh Verzweigungsmodelle – eine Frage der Benutzermeinung bleiben. Git-Branching-Modelle versprechen, den Schmerz zu lindern, indem sie das Chaos organisieren, das unweigerlich entsteht, wenn Softwareentwickler Änderungen an ihren Codebasen vornehmen.

Wie viele Entwickler wollten Sie etwas, das „einfach funktioniert“, damit Sie mit der eigentlichen Softwareentwicklung weitermachen können. Sie haben also Git flow aufgegriffen, ein Verzweigungsmodell, das Git-Benutzern oft empfohlen wird. Vielleicht waren Sie anfangs mit der Logik von Git Flow an Bord, bis Sie in der Praxis auf einige Probleme gestoßen sind. Oder vielleicht scheint Git Flow nicht gut genug zu sein, um es zu übernehmen. Schließlich spielen unzählige Variablen eine Rolle, und kein einzelnes Verzweigungsmodell wird in jeder Situation gut funktionieren.

Gute Nachrichten! Als Variation des klassischen Git-Flow-Modells vereinfacht der erweiterte Git-Flow die häufigeren Manöver des Git-Flow-Workflows, während die Hauptvorteile erhalten bleiben.

Glanz und Elend des klassischen Git-Flow-Modells

Ich bin ein starker Befürworter von Git Flow, seit ich entdeckt habe, wie es sich auszeichnet, wenn ein Produkt entwickelt wird, das sich in signifikanten Wertsteigerungen (mit anderen Worten, Releases ) entwickelt.

Ein signifikanter Wertzuwachs erfordert einen erheblichen Zeitaufwand, um abgeschlossen zu werden, wie die Sprints von mehr als zwei Wochen, die normalerweise in der Scrum-basierten Entwicklung verwendet werden. Wenn ein Entwicklungsteam bereits für die Produktion bereitgestellt hat, kann es zu Problemen kommen, wenn sich der Umfang der nächsten Version an derselben Stelle ansammelt, an der sich der Produktionscode befindet – z. B. im Hauptzweig des von ihnen verwendeten Git-Repositorys.

Während sich das Produkt noch in der anfänglichen Entwicklungsphase befindet – dh es gibt keine Produktion und es gibt keine echten Benutzer des Produkts – ist es für das Team in Ordnung, alles einfach im Hauptzweig zu belassen. Eigentlich ist es mehr als in Ordnung: Diese Strategie ermöglicht das schnellste Entwicklungstempo ohne großen Aufwand. Aber in einer Produktionsumgebung ändern sich die Dinge; dann verlassen sich echte Menschen darauf, dass das Produkt stabil ist.

Wenn es beispielsweise einen kritischen Fehler in der Produktion gibt, der sofort behoben werden muss, wäre es eine große Katastrophe für das Entwicklungsteam, die gesamte bisher im Hauptzweig angefallene Arbeit rückgängig machen zu müssen, nur um den Fix bereitzustellen. Und die Bereitstellung von Code ohne angemessene Tests – ob der Code als unausgegoren oder als gut entwickelt gilt – ist eindeutig keine Option.

Hier glänzen Verzweigungsmodelle, einschließlich Git-Flow. Jedes ausgeklügelte Verzweigungsmodell sollte Fragen dazu beantworten, wie man die nächste Version von der Version des Systems isoliert , die derzeit von Benutzern verwendet wird, wie man diese Version mit der nächsten Version aktualisiert und wie man Hotfixes für alle kritischen Fehler in die aktuelle Version einführt.

Der Git-Flow-Prozess adressiert diese grundlegenden Szenarien, indem er „Main“ (den Produktions- oder „aktuelle Version“-Branch) und „Develop“ (den Entwicklungs- oder „Next Release“-Branch) trennt und alle Regeln zur Verwendung von Feature-/Release-/Hotfix-Branchs bereitstellt . Es löst effektiv viele Probleme in den Entwicklungsworkflows von Release-basierten Produkten.

Aber selbst bei Projekten, die gut für das klassische Git-Flow-Modell geeignet sind, habe ich unter den typischen Problemen gelitten, die es mit sich bringen kann:

  • Der Git-Flow ist komplex, mit zwei langlebigen Zweigen, drei Arten von temporären Zweigen und strengen Regeln, wie Zweige miteinander umgehen. Diese Komplexität erhöht die Wahrscheinlichkeit von Fehlern und erhöht den Aufwand für deren Behebung.
  • Release- und Hotfix-Branches erfordern ein „doppeltes Zusammenführen“ – einmal in main, dann in development. Manchmal kann man vergessen, beides zu tun. Sie können die Git-Flussverzweigung mit Skripten oder VCS-GUI-Client-Plug-ins vereinfachen, aber Sie müssen sie zuerst für jeden Computer jedes Entwicklers einrichten, der an einem bestimmten Projekt beteiligt ist.
  • In CI/CD-Workflows erhalten Sie normalerweise zwei endgültige Builds für ein Release – eines aus dem letzten Commit des Release-Zweigs selbst und ein weiteres aus dem Merge-Commit zum Hauptverzeichnis. Genau genommen sollten Sie das aus dem Hauptteil verwenden, aber die beiden sind normalerweise identisch, was zu Verwechslungen führen kann.

Geben Sie „Erweiterter Git-Flow“ ein

Das erste Mal, dass ich den erweiterten Git-Flow verwendet habe, war bei einem Greenfield-Closed-Source-Projekt. Ich habe mit einem anderen Entwickler zusammengearbeitet, und wir haben an dem Projekt gearbeitet, indem wir uns direkt auf den Hauptzweig festgelegt haben.

Hinweis: Bis zur ersten öffentlichen Veröffentlichung eines Produkts ist es aus Gründen der Geschwindigkeit und Einfachheit des Entwicklungsworkflows absolut sinnvoll, alle Änderungen direkt in den Hauptzweig zu übertragen – selbst wenn Sie ein Git-Flow-Befürworter sind. Da es noch keine Produktion gibt, besteht keine Möglichkeit eines Produktionsfehlers, den das Team so schnell wie möglich beheben muss. Die ganze Verzweigungsmagie, die der klassische Git-Flow impliziert, ist daher zu diesem Zeitpunkt übertrieben.

Dann näherten wir uns der ersten Veröffentlichung und waren uns einig, dass wir uns über diesen Punkt hinaus nicht mehr wohl fühlen würden, wenn wir uns direkt auf den Hauptzweig festlegen würden. Wir waren ziemlich schnell vorangekommen, und geschäftliche Prioritäten ließen nicht viel Raum, um einen felsenfesten Entwicklungsprozess zu etablieren – dh einen mit ausreichend automatisierten Tests, um uns die Gewissheit zu geben, dass unser Hauptzweig in einem releasefähigen Zustand bleibt.

Es schien ein gültiger Fall für das klassische Git-Flow-Modell zu sein. Mit getrennten Haupt- und Entwicklungszweigen und genügend Zeit zwischen signifikanten Werterhöhungen bestand die Zuversicht, dass die überwiegend manuelle QA zu ausreichend guten Ergebnissen führen würde. Als ich mich für Git Flow aussprach, schlug mein Kollege etwas Ähnliches vor, jedoch mit einigen wesentlichen Unterschieden.

Zuerst habe ich zurückgedrängt. Einige der vorgeschlagenen „Patches“ für den klassischen Git-Flow erschienen mir etwas zu revolutionär. Ich dachte, sie könnten die Hauptidee brechen, und der gesamte Ansatz würde zu kurz kommen. Aber bei weiterem Nachdenken wurde mir klar, dass diese Optimierungen den Git-Fluss nicht wirklich unterbrechen. In der Zwischenzeit machen sie es zu einem besseren Git-Branching-Modell, indem sie alle oben genannten Schwachstellen lösen.

Nach dem Erfolg mit dem modifizierten Ansatz in diesem Projekt habe ich ihn in einem anderen Closed-Source-Projekt mit einem kleinen Team dahinter verwendet, wo ich der ständige Eigentümer der Codebasis war und ein oder zwei ausgelagerte Entwickler von Zeit zu Zeit halfen. Bei diesem Projekt gingen wir sechs Monate in die Produktion und seitdem verwenden wir CI- und E2E-Tests seit über einem Jahr, mit Releases etwa jeden Monat.

Ein typisches Git-Commit-Diagramm bei Verwendung des erweiterten Git-Flusses. Das Diagramm zeigt ein paar Commits bei „develop“ und „main“ und vor ihrem gemeinsamen Commit mehrere datumsbasierte Tags.

Meine Gesamterfahrung mit diesem neuen Branching-Ansatz war so positiv, dass ich sie mit meinen Entwicklerkollegen teilen wollte, um ihnen zu helfen, die Nachteile des klassischen Git-Flows zu umgehen.

Ähnlichkeiten mit klassischem Git-Flow: Entwicklungsisolation

Für die Arbeitsisolation im erweiterten Git-Fluss gibt es immer noch zwei langlebige Branches, main und development. (Benutzer haben immer noch Hotfix- und Release-Fähigkeiten – mit Betonung auf „Fähigkeiten“, da dies keine Verzweigungen mehr sind. Wir werden im Abschnitt „Unterschiede“ auf Details eingehen.)

Es gibt kein offizielles Benennungsschema für klassische Git-Flow-Funktionszweige. Sie verzweigen sich einfach von der Entwicklung und führen sie wieder in die Entwicklung ein, wenn das Feature fertig ist. Teams können jede beliebige Namenskonvention verwenden oder einfach hoffen, dass Entwickler aussagekräftigere Namen als „my-branch“ verwenden. Dasselbe gilt für den erweiterten Git-Fluss.

Alle Features, die sich bis zu einem gewissen Schnittpunkt im Entwicklungszweig angesammelt haben, werden die neue Version prägen.

Squash-Merges

Ich empfehle dringend, Squash-Merge für Feature-Branches zu verwenden, um den Verlauf die meiste Zeit schön und linear zu halten. Ohne sie beginnen Commit-Graphen (von GUI-Tools oder git log --graph ) schlampig auszusehen, wenn ein Team auch nur mit einer Handvoll Feature-Branches jongliert:

Vergleich des Commit-Diagramms, das aus einer Squash-Merge-Strategie resultiert, mit dem Commit-Diagramm, das aus einer Merge-Commit-Strategie resultiert. Der primäre Zweig des anfänglichen Git-Commit-Graphen ist mit „develop“ bezeichnet, wobei ein früherer Commit „feature-D“ und „feature-C“ davon abzweigt und ein noch früherer Commit „feature-B“ und „feature-A“ hat “ davon abzweigen. Das Merge-Commit-Ergebnis sieht ähnlich aus, aber jeder Feature-Zweig verursacht einen neuen Commit beim Entwickeln an dem Punkt, an dem er damit verbunden ist. Das Squash-Merge-Ergebnis ist einfach eine gerade Linie von Commits ohne andere Zweige.

Aber selbst wenn Sie mit der Optik in diesem Szenario einverstanden sind, gibt es noch einen weiteren Grund, es zu kürzen. Ohne zu quetschen, erzählen Commit-Verlaufsansichten – darunter sowohl einfaches git log (ohne --graph ) als auch GitHub – selbst bei den einfachsten Merge-Szenarien ziemlich zusammenhangslose Geschichten:

Vergleich der Commit-Verlaufsansicht, die sich aus einer Squash-Merge-Taktik ergibt, mit der, die sich aus einer Merge-Commit-Taktik ergibt. Der ursprüngliche Repo-Zustand wird in Zeitleistenform angegeben und zeigt die Chronologie der Commits an zwei Feature-Branches, die von einem gemeinsamen Commit „x“ bei der Entwicklung stammen, wobei Commits zwischen den Branches wechseln, nämlich in der Reihenfolge 1a, 2a, 1b und 2b. Merge-Commit-Ergebnisse werden in zwei Variationen angezeigt. In der Commit-Historie, die sich aus dem Zusammenführen des zweiten Zweigs, dem Zusammenführen des ersten Zweigs und dem anschließenden Löschen beider Zweige ergibt, ist die Geschichte chronologisch, aber nicht zusammenhängend, und enthält einen zusätzlichen Merge-Commit für den ersten Zweig. In der Historie, die sich aus dem Zusammenführen der Branches in der Reihenfolge vor dem Löschen ergibt, sind die Commits geordnet, „x, 2a, 1a, 2b, 1b“, gefolgt vom Merge-Commit für den zweiten Branch, der nicht einmal chronologisch ist. Der Commit-Verlauf von Squash Merging hat einfach einen einzigen Commit für jeden Feature-Zweig, wobei die Geschichte jedes Zweigs vom Committer erzählt wird.

Der Nachteil bei der Verwendung von Squash-Merging ist, dass der ursprüngliche Feature-Branch-Verlauf verloren geht. Aber dieser Vorbehalt gilt nicht einmal, wenn Sie beispielsweise GitHub verwenden, das den vollständigen ursprünglichen Verlauf eines Feature-Zweigs über die per Squash zusammengeführte Pull-Anforderung offenlegt, selbst nachdem der Feature-Zweig selbst gelöscht wurde.

Unterschiede zum klassischen Git-Flow: Releases und Hotfixes

Lassen Sie uns den Veröffentlichungszyklus durchgehen, da dies (hoffentlich) die Hauptsache ist, die Sie tun werden. Wenn wir an dem Punkt angelangt sind, an dem wir veröffentlichen möchten, was sich in der Entwicklung angesammelt hat, handelt es sich ausschließlich um eine Obermenge von main. Danach beginnen die größten Unterschiede zwischen klassischem und erweitertem Git-Flow.

Git-Commit-Graphen, wie sie sich ändern, wenn eine normale Veröffentlichung unter erweitertem Git-Fluss durchgeführt wird. Das anfängliche Diagramm hat eine Hauptabweichung von mehreren Commits hinter der Spitze und von einem Commit. Nach dem Tagging sind main und vYYYY-MM-DD gleich. Nach dem Löschen der lokalen Hauptdatei, dem Erstellen an der Spitze von „Develop“, dem Erzwingen von Pushen, Bereitstellen, Testen usw. wird „Main“ auch mit „Develop“ angezeigt, wobei vYYYY-MM-DD dort bleibt, wo ursprünglich „Main“ war. Nach dem Deployment-/Test-Zyklus, Staging-Fixes auf main (schließlich Squash zusammengeführt in development) und zwischenzeitlich nicht zusammenhängenden Änderungen auf development, weist das endgültige Diagramm Develop und Main auf, jeweils mit mehreren Commits, von wo aus sie gleichmäßig miteinander verbunden waren die vorherige Grafik.

Veröffentlichungen im erweiterten Git-Flow

Jeder Schritt beim Erstellen eines Releases mit erweitertem Git-Flow unterscheidet sich vom klassischen Git-Flow-Prozess:

  1. Releases basieren eher auf Main als auf Developer. Markieren Sie den aktuellen Tipp des Hauptasts mit etwas Sinnvollem. Ich habe Tags basierend auf dem aktuellen Datum im ISO 8601-Format mit vorangestelltem „v“ übernommen, z. B. v2020-09-09 .
    • Wenn es an einem Tag mehrere Veröffentlichungen gibt – zum Beispiel Hotfixes – kann das Format je nach Bedarf mit einer fortlaufenden Nummer oder einem Buchstaben versehen werden.
    • Beachten Sie, dass die Tags im Allgemeinen nicht den Veröffentlichungsdaten entsprechen. Sie sollen Git lediglich dazu zwingen, einen Verweis darauf zu behalten, wie der Hauptzweig aussah, als der nächste Veröffentlichungsprozess begann.
  2. Pushen Sie das Tag mit git push origin <the new tag name> .
  3. Danach eine kleine Überraschung: Löschen Sie Ihre lokale Hauptniederlassung . Keine Sorge, wir werden es in Kürze wiederherstellen.
    • Alle Commits an main sind immer noch sicher – wir haben sie vor der Garbage Collection geschützt, indem wir im vorherigen Schritt main markiert haben. Jeder dieser Commits – sogar Hotfixes, wie wir gleich behandeln werden – ist auch Teil von development.
    • Stellen Sie einfach sicher, dass nur eine Person in einem Team dies für eine bestimmte Version tut; das ist die sogenannte „Release Manager“-Rolle. Ein Release Manager ist normalerweise das erfahrenste und/oder dienstälteste Teammitglied, aber ein Team tut gut daran, zu vermeiden, dass ein bestimmtes Teammitglied diese Rolle dauerhaft übernimmt. Sinnvoller ist es, Wissen im Team zu verbreiten, um den berüchtigten Bus-Faktor zu erhöhen.
  4. Erstellen Sie einen neuen lokalen Hauptzweig am Tip-Commit Ihres Entwicklungszweigs .
  5. Pushen Sie diese neue Struktur mit git push --force , da das entfernte Repo eine so „drastische Änderung“ nicht so einfach akzeptiert. Auch dies ist nicht so unsicher, wie es in diesem Zusammenhang erscheinen mag, denn:
    • Wir verschieben lediglich den Hauptzweigzeiger von einem Commit zu einem anderen.
    • Diese Änderung wird jeweils nur von einem bestimmten Teammitglied vorgenommen.
    • Die tägliche Entwicklungsarbeit findet im Develop-Zweig statt, sodass Sie die Arbeit von niemandem stören, indem Sie auf diese Weise in den Hauptzweig wechseln.
  6. Sie haben Ihre Neuerscheinung! Stellen Sie es in der Staging-Umgebung bereit und testen Sie es. (Wir werden weiter unten praktische CI/CD-Muster besprechen.) Alle Korrekturen gehen direkt an den Hauptzweig, und er wird deshalb beginnen, vom Entwicklungszweig abzuweichen.
    • Gleichzeitig können Sie im Entwicklungszweig mit der Arbeit an einem neuen Release beginnen, derselbe Vorteil wie im klassischen Git-Flow.
    • Für den unglücklichen Fall, dass zu diesem Zeitpunkt ein Hotfix für das benötigt wird, was sich derzeit in der Produktion befindet (nicht für die bevorstehende Version in der Bereitstellung), finden Sie weitere Einzelheiten zu diesem Szenario unter „Umgang mit Hotfixes während einer aktiven Version…“.
  7. Wenn Ihre neue Version als stabil genug erachtet wird, stellen Sie die endgültige Version in der Produktionsumgebung bereit und führen Sie einen einzigen Squash-Merge von main to development durch, um alle Fixes aufzunehmen.

Hotfixes im erweiterten Git-Flow

Hotfix-Fälle sind zweierlei. Wenn Sie einen Hotfix machen, ohne dass es eine aktive Version gibt – dh das Team bereitet eine neue Version im Entwicklungszweig vor – ist es ein Kinderspiel: Commit to main, lassen Sie Ihre Änderungen bereitstellen und im Staging testen, bis sie fertig sind für die Produktion bereitstellen.

Wählen Sie als letzten Schritt Ihr Commit von „main“ bis „development“ aus, um sicherzustellen, dass die nächste Version alle Fixes enthält. Falls Sie am Ende mehrere Hotfix-Commits haben, sparen Sie Aufwand – insbesondere wenn Ihre IDE oder ein anderes Git-Tool dies ermöglichen kann – indem Sie einen Patch erstellen und anwenden, anstatt mehrmals Rosinen herauszupicken. Der Versuch, Merge Main zur Entwicklung nach der ersten Veröffentlichung zu quetschen, wird wahrscheinlich zu Konflikten mit dem unabhängigen Fortschritt im Entwicklungszweig führen, daher empfehle ich das nicht.

Der Umgang mit Hotfixes während einer aktiven Version – dh wenn Sie nur Push-Main erzwingen und immer noch die neue Version vorbereiten – ist der schwächste Teil des erweiterten Git-Flusses. Je nach Länge Ihres Release-Zyklus und Schweregrad des Problems, das Sie lösen müssen, sollten Sie immer darauf abzielen, Fixes in das neue Release selbst aufzunehmen – das ist der einfachste Weg und wird den gesamten Arbeitsablauf überhaupt nicht stören.

Falls das ein No-Go ist – Sie müssen schnell einen Fix einführen und können es kaum erwarten, bis die neue Version fertig ist – dann machen Sie sich bereit für eine etwas komplizierte Git-Prozedur:

  1. Erstellen Sie einen Zweig – wir nennen ihn „Neuveröffentlichung“, aber Ihr Team kann hier jede beliebige Namenskonvention übernehmen – mit demselben Commit wie der aktuelle Tipp von main. Neuerscheinung pushen.
  2. Löschen Sie den lokalen Hauptzweig am Commit des Tags, das Sie zuvor für die aktuelle aktive Version erstellt haben, und erstellen Sie ihn neu. Push-Main erzwingen.
  3. Führen Sie die erforderlichen Fixes in main ein, stellen Sie sie in der Staging-Umgebung bereit und testen Sie sie. Sobald dies fertig ist, stellen Sie es in der Produktion bereit.
  4. Geben Sie Änderungen von der aktuellen Hauptversion an die neue Version weiter, entweder per Cherry-Picking oder einem Patch.
  5. Wiederholen Sie danach die Release-Prozedur: Taggen Sie die Spitze des aktuellen Mains und pushen Sie das Tag, löschen und erstellen Sie den lokalen Main an der Spitze des New-Release-Zweigs neu und erzwingen Sie Push Main.
    1. Sie werden das vorherige Tag wahrscheinlich nicht benötigen, also können Sie es entfernen.
    2. Der New-Release-Zweig ist jetzt überflüssig, sodass Sie ihn auch entfernen können.
  6. Sie sollten jetzt wie gewohnt mit einer neuen Version loslegen können. Schließen Sie ab, indem Sie die Notfall-Hotfixes von main über Rosinenpickerei oder einen Patch verbreiten.

Git-Commit-Diagramme, wie sie sich ändern, wenn ein Hotfix während einer aktiven Version unter erweitertem Git-Fluss durchgeführt wird. Das Startdiagramm hat sich als die längste Reihe von Commits entwickelt, wobei zwei Commits zuvor um ein Commit und drei Commits davor auseinandergingen, der a-Zweig um ein Commit divergierte, gekennzeichnet mit v2020-09-18. Nach den ersten beiden obigen Schritten hat der Graph dann new-release, wo früher main war, und main ist nicht einmal mit v2020-09-18. Die restlichen Schritte werden dann ausgeführt, was zum endgültigen Diagramm führt, in dem main ein Commit vor der Position von new-release ist und v2020-09-20 ein Commit vor der Position von v2020-09-18 ist.

Bei richtiger Planung, ausreichend hoher Codequalität und einer gesunden Entwicklungs- und Qualitätssicherungskultur ist es unwahrscheinlich, dass Ihr Team diese Methode verwenden muss. Es war ratsam, einen solchen Notfallplan für einen verbesserten Git-Fluss zu entwickeln und zu testen, nur für den Fall – aber ich musste ihn nie in der Praxis verwenden.

CI/CD-Setup zusätzlich zum erweiterten Git-Flow

Nicht jedes Projekt erfordert eine dedizierte Entwicklungsumgebung. Es kann einfach genug sein, auf jedem Entwicklercomputer eine ausgeklügelte lokale Entwicklungsumgebung einzurichten.

Aber eine dedizierte Entwicklungsumgebung kann zu einer gesünderen Entwicklungskultur beitragen. Durch das Ausführen von Tests, das Messen der Testabdeckung und das Berechnen von Komplexitätsmetriken im Entwicklungszweig werden häufig die Kosten von Fehlern gesenkt, indem sie erkannt werden, bevor sie in der Staging-Umgebung landen.

Ich fand einige CI/CD-Muster besonders nützlich, wenn sie mit einem verbesserten Git-Fluss kombiniert wurden:

  • Wenn Sie eine Entwicklungsumgebung benötigen, richten Sie CI so ein, dass es bei jedem Commit in den Entwicklungszweig erstellt, getestet und bereitgestellt wird. Passen Sie hier auch E2E-Tests an, wenn Sie es haben und es in Ihrem Fall Sinn macht.
  • Richten Sie CI zum Erstellen, Testen und Bereitstellen in der Staging-Umgebung bei jedem Commit zum Hauptzweig ein. E2E-Tests sind auch an dieser Stelle sehr vorteilhaft.
    • Es mag überflüssig erscheinen, E2E-Tests an beiden Stellen zu verwenden, aber denken Sie daran, dass Hotfixes in der Entwicklung nicht vorkommen. Durch das Auslösen von E2E bei Commits an main werden Hotfixes und alltägliche Änderungen getestet, bevor sie veröffentlicht werden, aber auch durch das Auslösen von Commits zur Entwicklung werden Fehler früher erkannt.
  • Konfigurieren Sie CI so, dass Ihr Team auf manuelle Anfrage hin Builds von der Haupt- in die Produktionsumgebung bereitstellen kann.

Die empfohlene Einrichtung von CI/CD mit erweitertem Git-Fluss, wenn zusätzlich zu Staging („stage“) und Produktion („prod“) eine Entwicklungsumgebung („dev“) vorhanden ist. Alle Commits auf dem Zweig development führen zu einem Build, der auf dev bereitgestellt wird. Ebenso führen alle Commits zum Hauptergebnis zu einem Build, der in die Phase bereitgestellt wird. Eine manuelle Anforderung eines bestimmten Commits aus den Hauptergebnissen führt zu einem Build, der in der Produktion bereitgestellt wird.

Solche Muster sind relativ einfach, bieten jedoch leistungsstarke Maschinen zur Unterstützung des täglichen Entwicklungsbetriebs.

Das erweiterte Git-Flow-Modell: Verbesserungen und mögliche Einschränkungen

Enhanced Git Flow ist nicht jedermanns Sache. Es nutzt die umstrittene Taktik, den Hauptzweig mit Gewalt voranzutreiben, so dass Puristen es ablehnen können. Aus praktischer Sicht ist daran jedoch nichts auszusetzen.

Wie bereits erwähnt, sind Hotfixes während eines Releases schwieriger, aber immer noch möglich. Mit der richtigen Aufmerksamkeit für QA, Testabdeckung usw. sollte das nicht allzu oft passieren, daher ist es aus meiner Sicht ein gültiger Kompromiss für die Gesamtvorteile des erweiterten Git-Flows im Vergleich zum klassischen Git-Flow. Mich würde sehr interessieren, wie der verbesserte Git-Flow in größeren Teams und bei komplexeren Projekten abschneidet, bei denen Hotfixes möglicherweise häufiger vorkommen.

Meine positiven Erfahrungen mit dem erweiterten Git-Flow-Modell drehen sich auch hauptsächlich um kommerzielle Closed-Source-Projekte. Dies kann für ein Open-Source-Projekt problematisch sein, bei dem Pull-Requests häufig auf einer alten Release-Ableitung des Quellbaums basieren. Es gibt keine technischen Hürden, um das zu lösen – es könnte nur mehr Aufwand erfordern als erwartet. Ich freue mich über Rückmeldungen von Lesern mit viel Erfahrung im Open-Source-Bereich bezüglich der Anwendbarkeit des erweiterten Git-Flusses in solchen Fällen.

Besonderer Dank gilt dem Toptal-Kollegen Antoine Pham für seine Schlüsselrolle bei der Entwicklung der Idee hinter dem verbesserten Git-Fluss.


Weiterführende Literatur im Toptal Engineering Blog:

  • Trunk-basierte Entwicklung vs. Git Flow
  • Git-Workflows für Profis: Ein guter Git-Leitfaden

Microsoft Gold Partner-Abzeichen.

Als Microsoft Gold Partner ist Toptal Ihr Elite-Netzwerk von Microsoft-Experten. Bauen Sie leistungsstarke Teams mit den Experten auf, die Sie brauchen – überall und genau dann, wenn Sie sie brauchen!