Drie strategieën om jouw Git-repository te structureren
Ontdek de kunst van het structureren van Git-repositories. Ik duik in de wereld van Git-workflows en presenteer je drie robuuste strategieën om je codebase georganiseerd en efficiënt te houden:
- Github Flow Main - Feature
- Git Flow Main - Develop - Feature
- Gitlab Flow x.x - Main - Feature
Voor elke strategie verken ik de mogelijkheden, leg ik uit hoe je deze kunt implementeren, en weeg ik de voor- en nadelen tegen elkaar af. Uiteindelijk laat ik de keuze aan jou over. Deze blog is geschreven voor ontwikkelaars die al bekend zijn met Git en dient ook als een waardevolle bron voor de interne documentatie van Q2-software.nl.
Op welke manier kan je Git-versiebeheer structureren?
1: Github Flow: Main - Feature
De meest eenvoudige manier om je repository te structureren is met twee branches: main
en feature-x
. Deze manier is geïnspireerd op Github Flow en is zeer geschikt voor het principe continuous delivery.
Met twee branches kan je een lokale testomgeving en een online testomgeving draaien op de feature-branches. De main-branch is default en protected tegelijk. main
is alleen bedoeld voor je productie omgeving. Wanneer je feature getest en stabiel is mag er een merge plaatsvinden van de feature-branch naar de main-branch. Het is van belang dat je de merge feature-x to main
kunt testen vóórdat deze naar productie gaat*.
Github Flow is goed te doen als je in je eentje aan een project werkt. Je kunt zelf overzicht houden wat er ontwikkeld is en je hoeft weinig rekening te houden met andere merges (of je weet precies wat er aan de hand is omdat je zelf de merge gemaakt hebt). Het werkt ook met open-source projecten (en dus meerdere devs), maar wel met één persoon die het overzicht houdt.
*Sommigen maken hiervoor een release-branch aan zodat ze die kunnen uitrollen in een test- of acceptance omgeving. Dit laten we echter voor de eenvoud buiten beschouwing.
2: Git Flow: Main - Develop - Feature
Een iets complexere manier van structureren is het werken Git Flow. Dit werkt met de bovengenoemde main-develop structuur, maar voor elke feature die je ontwikkelt maak je een nieuwe branch. Deze branch heet zoiets als feature-x
of issue-x
. Git Flow is een veel voorkomende manier van structureren als je in een ontwikkelteam werkt met twee of meer developers. Iedere developer werkt aan zijn eigen feature, test deze en doet een pull-request naar de develop-branch.
In deze structuur blijft de main
protected en de develop
default.
Op je lokale ontwikkelomgeving werk je voornamelijk op een feature-branch en soms op de develop-branch. Develop
zit verder gekoppeld aan een online testomgeving (vaak met automatisch deployment). Wanneer een versie klaar is om volledig getest te worden wordt een acceptance omgeving opgezet waar de volgende release klaarstaat. Wanneer dit akkoord is wordt die versie de volgende stable-version*.
Deze manier van structureren is erg overzichtelijk omdat je alleen te maken hebt met veel feature-branches, maar het voordeel is dat alle features op dezelfde broncode zijn gebaseerd; namelijk de develop
. Terug mergen leidt meestal niet tot heel veel problemen.
Het nadeel van deze strategie is dat het je releasecyclus kan vertragen omdat een bepaalde feature niet geaccepteerd wordt. Alle overige features die in deze release werden ontwikkeld moeten nu wachten tot het moment dat de vertraagde feature ook ready of verwijderd is.
*Sommigen maken van deze versie een release branch, maar voor de eenvoud laten we dat buiten beschouwing.
3: Gitlab Flow: x.x - Main - Feature
De meest ingewikkelde structuur is direct ook de meest dynamische structuur. Ga er even voor zitten.
Stel je voor dat je aan meerdere releases tegelijk werkt. De vorige twee strategieën voorzien niet in deze behoefte. Je hebt een project waarvan een versie 1 in productie is, maar waar nog diverse fixes aan moeten gebeuren. Tegelijk is de ontwikkeling van de volgende versie al gestart. Dit zou bij Git Flow tot veel conflicten kunnen leiden, want er zouden fixes van versie 1 en features van de ontwikkelversie door elkaar op de develop-branch terecht komen. Bij Github Flow zou de ontwikkeling naast elkaar goed gaan, maar is het testen van de features een grotere uitdaging omdat dan alles alsnog bij elkaar komt. In beide gevallen is het onoverzichtelijk welke versie er bij een nieuwe release nu precies wordt uitgerolt. Alleen de fixes of ook nieuwe features of alleen nieuwe features en geen fixes?
Een manier om Gitlab Flow te implementeren is alle x.x
-branches protected te maken. De main
is default en feature-x
zijn alle feature-branches die gebaseerd worden op de main-branch. Wanneer er een release klaar is maak je een aftakking van de main-branch die je x.x
noemt. Let wel op: dit is één van de vele manieren om deze structuur te implementeren. Laten we eens een voorbeeld bekijken.
Het Laravel Framework. Laravel versie 11 is actief, maar ze supporten versie 10 ook nog een jaar. Dat kan alleen als ze meerdere productie- en development-branches naast elkaar draaien. En dat is ook zo:
10.x
is waar de patches voor versie 10 worden gemaakt terwijl11.x
de default-branch is waar nieuwe features en fixes in versie 11 worden ontwikkeld.
Wat maakt het complex? Vaak is het moeilijk om een fix van de ene versie direct uit te rollen (of te mergen) naar de andere versie. Beide versies hebben namelijk een andere bron. In tegenstelling tot Github Flow en Git Flow (met beiden 1 development bron) heb je hier te maken met een 10.x-dev
-branch én met een 11.x-dev
-branch. Dat zijn verschillende bronnen met een steeds verder uit elkaar liggende versie van de code. Blind mergen van een patch op 10.x-dev
naar 11.x-dev
zal mogelijk leiden tot bugs in versie 11 omdat de broncode daar anders is. Vaak programmeer je patches twee keer. Dit is niet zo’n probleem, omdat een patch meestal eerst als een hotfix op de productie wordt toegepast en later in de volgende versie als een uitgebreide reparatie of verbetering wordt verwerkt. Het meeste denkwerk gebeurt in één versie, dus het overzetten naar de andere versie gaat meestal vrij snel.
Vergelijking
1. Github Flow | 2. Git Flow | 3. Gitlab Flow | |
---|---|---|---|
Branches | main | main develop | x.x main |
Ondersteunende branches | feature-x | feature-x | feature-x patch-x |
Aantal eigenaren/devs | 1 | 2+ | 2+ |
Development | develop | feature | feature |
Testen | develop | develop | main |
Acceptance | main | main | x.x |
Release branches | Meh… 🤷♂️ | Meh… 🤷♂️ | Ja 👍 |
Meerdere versies mogelijk? | Nee 👎 | Meh… 🤷♂️ | Ja 👍 |
Continuous Delivery | Ja 👍 | Nee 👎 | Ja 👍 |
Onderhoudbaarheid Git-repo | Eenvoudig | Eenvoudig | Moeilijker |
Conclusie
Werk je alleen aan een project? Houd het simpel en ga voor Github Flow, tenzij een andere strategie echt tijd bespaart. Werk je in een (klein) ontwikkelteam? Kies dan voor Git Flow tenzij je meerdere productieversies nodig hebt. Git Flow helpt je om codeconflicten te verminderen en maakt het makkelijker om wijzigingen te beoordelen via pull-requests. Zeker als je project open-source is, werkt dat fijn. Bij meerdere ontwikkel- of productieversies is het te overwegen om voor Gitlab Flow te gaan, maar wees je bewust van de extra managementinspanningen en dat fixes extra aandacht vragen en dubbel werk kunnen opleveren.