Gebruik Gitflow, verantwoord



Crowd of passengers having fun in a bustling city on a vibrant floor

Published on May 2017 by Arjan Franzen

Versiebeheer is en blijft waarschijnlijk een onderwerp van debat. Soms lijkt het alsof we zoeken naar één ‘beste’ manier om in alle omstandigheden versies van code te beheren. Sinds circa 2008 is git sterk in populariteit gestegen en sinds 2012 is het het populairste versiebeheersysteem. Dat leidde tot een nieuwe ronde discussies over hoe u het meest gebruikte versiebeheersysteem van dat moment — git — inzet. Nu we in 2017 zitten: is het stof neergedaald en zijn er conclusies?

Hoewel git conceptueel sterk verschilt van zijn concurrenten — het is een gedistribueerd versiebeheersysteem en de andere oudere populaire systemen waren niet‑gedistribueerd (Mercurial uitgezonderd). Geen centrale server nodig hebben is cruciaal in een open‑source‑omgeving; voor closed source in een bedrijfsomgeving is het minder essentieel, maar het opent veel nieuwe mogelijkheden. Of een systeem gedistribueerd is of niet, maakt voor het branching‑beleid niet heel veel uit. Met een gedistribueerd systeem heeft iedereen een volledige, gezaghebbende kopie van alle codeversies. Een centraal git‑repository is alleen centraal omdat u het zo afspreekt, in plaats van zoals vroeger, met één server waar alle anderen client van waren.

Centrale vragen in gebruik/beleid rond softwareversies waren, zijn en blijven wellicht:

  • When do you branch?

  • What branches are there?

  • When do you merge?

Als u een branching‑beleid standaardiseert, zijn er een paar opties: Gitflow, Github flow en Gitlab flow. Vanwege de populariteit bespreek ik hier alleen de eerste twee: Gitflow en Github flow.

Gitflow

Voor het eerst beschreven door Vincent Driessen in 2010 en uitgebreid op zijn blog beschrijft het een eenvoudige manier om git te gebruiken met een aantal standaardbranches, elk met een eigen doel:

  • master: Stable software only, everything that is pushed to production. production ready software lives here

  • develop: Integration and ongoing development: things that will be in the next release

Daarnaast zijn er drie ondersteunende branches voor de workflow:

  • feature: are branches off develop for a "feature development" this is where the main debate is.

  • release: link between master and develop done for integration work

  • hotfix: branch off master for emergency fix

Hieronder staat een diagram met alle branch‑typen en hoe ze terug mergen naar hun bronbranch.

Gitflow branch types: feature and release branches leaving develop and merging back, and a hotfix branch on main.

Gitflow branch types: feature and release branches leaving develop and merging back, and a hotfix branch on main.

Het gitflow‑proces is eenvoudig, beproefd en een prima startpunt. Zeker als uw huidige deployment‑proces 100% release‑georiënteerd is en veel handwerk bevat. Er zijn wel wat nadelen, of ‘misgedrag’, die ik in de praktijk heb gezien. De belangrijkste is het beleid om voor alles. Stap 1 in dit antipatroon is: een featurebranch aanmaken zodra u aan een nieuw item begint (Bug, Feature, Fix, Improvement). Een negatief gevolg is dat de maker van de branch minder gaat communiceren met de buitenwereld (team, andere teams). Dat patroon werkt naar mijn idee averechts op een gezond versiebeheerbeleid.

Github-flow

Als alternatief voor gitflow beschreven de mensen bij github hun versiebeheerproces. Het is duidelijk gebaseerd op gitflow maar er is het nodige uitgehaald: feitelijk een versimpelde gitflow. github deed dit om zeer frequente releases mogelijk te maken.

GitHub flow: one long-lived main branch with short feature branches, released straight from main.

GitHub flow: one long-lived main branch with short feature branches, released straight from main.

Zoals u in het diagram ziet is dit een eenvoudiger manier van branchen en mergen. Het uitgangspunt is dat u in principe op de master‑branch werkt. Alleen als u vermoedt dat features bij het mergen problemen kunnen geven, of als u snel en toch stabiel wilt werken via bijvoorbeeld feature toggles of branch by abstraction, maakt u er een aparte branch voor: een featurebranch. Na afronding merge u de featurebranch terug naar master.

Naar CI

Nu de achtergrond van versiebeheerbeleid is behandeld, is het tijd er één te kiezen en toe te passen. Begin met een analyse van de componenten en systemen, en hoe die nu onder versiebeheer worden aangestuurd. Zijn de integratiecycli lang en releaset u 1 à 2 keer per jaar? Dan gebruikt u waarschijnlijk geen van beide beschreven methoden. Grote kans dat u iets traditionelers hanteert: elke aankomende release heeft een eigen projectbranch. Dat is ingericht op de volgende grote release, niet op features.

De overstap van zo’n model naar gitflow is relatief klein: zorg dat alle ontwikkeling eerst in de 'develop'-branch integreert en laat teams, waar nodig, samenwerken op dezelfde component. Externe stakeholders bij de teams — architecten, leads, ‘component stewards’ — spelen een actieve rol in het faciliteren van gelijktijdige wijzigingen op gedeelde componenten, zonder poortwachter, rechter en jury te worden. Adoptie kost tijd: alle teams moeten deze nieuwe manier van werken accepteren. Als engineers hebben we de neiging ons meer als component‑dictators dan als component‑stewards te gedragen. Sommige engineers doen er alles aan om te verdedigen dat zij, en alleen zij, een wijziging aan een component mogen doorvoeren. Soms wordt dat zelfs vastgelegd in branching‑policies. Het langetermijndoel is niet dat alle engineers altijd alles kunnen aanpassen, maar dat het beleid geen wrijving veroorzaakt in het naar productie brengen van wijzigingen. Een dictator‑gedreven bottleneck is zo’n vorm van wrijving die we zo snel mogelijk moeten verwijderen.

Nu is er een eenvoudig versiebeheerbeleid en verandert uw leveringsproces. De volgende stap is om steeds meer featurebranches te schrappen. Na het invoeren van gitflow zullen engineers in alle teams ze namelijk vaak standaard aanmaken. De reden om die massale aanmaak terug te dringen is het communicatieverlies tussen mensen en teams. Iedere vorm van branching veroorzaakt communicatie‑erosie. Dat kan al tussen twee mensen in hetzelfde team spelen. Met een branch creëert u een geïsoleerde wereld voor uzelf of uw team: u hoeft niet meer af te stemmen met anderen die mogelijk aan dezelfde code werken. Doet u dit te lang (langer dan één dag), dan loopt u kans op gemiste afstemming. Dat leidt tot mergeconflicten, maar vooral tot gemiste leerkansen met collega’s. Met tijdige communicatie en coördinatie had u kunnen refactoren of het zo kunnen ontwerpen dat beide features passen.

Vergeleken met gitflow is github‑flow minder belastend qua branching: het schrijft minder branches voor en is geschikter voor kleinere batches (releases). Deze werkwijze is ideaal voor Continuous Delivery en is in feite een echte Continuous Integration‑strategie. Niet voor iedereen, overigens. U kunt het vergelijken met Lean in productieomgevingen: een kenmerk van Lean is streven naar zo weinig mogelijk voorraad. De slechtste manier om dat te bereiken is in één keer alle magazijnstellingen weghalen. Streven naar minder voorraad betekent dat u minder stellingen krijgt, in time. Hetzelfde geldt voor Continuous Integration. Alle branching vormt een soort tussenvoorraad: als uw proces nu veel voorraad kent (heel veel branches), past gitflow in eerste instantie beter. Pas in time — met veel aandacht voor architectuur, workflow en processen en via continu verbeteren — kunt u die voorraad verlagen. U gaat in kleinere batches releasen en merkt dat gitflow‑branching u begint te hinderen. Vlak voor dat moment is het tijd om van gitflow naar github‑flow te schakelen.

Featurebranches kunnen door de staat van de software noodzakelijk zijn. Toch moet u er wat mij betreft naar streven er zo veel mogelijk te vermijden. Een directe maatregel is om het aanmaken van een featurebranch conditioneel te maken. Met zo’n eenvoudig beleid stimuleert u teams om continu samen te werken aan gedeelde componenten via gemeenschappelijke branches en leveringen. Die gezonde spanning tussen teams zou verbeteringen moeten opleveren, zodat meerdere wijzigingen parallel op één component kunnen plaatsvinden. Misschien moet de component niet langer gedeeld zijn en opgesplitst worden. Dat hangt af van de inspanningen van het team in het technische ontwerp van de producten.

Conclusie

Uiteindelijk haalt u, door terughoudend te zijn met featurebranches binnen gitflow, een paar hoofd­risico’s weg. Die risico’s hangen allemaal samen met vertraagde communicatie en leiden tot mergeconflicten, defects, technische schuld en optimalisaties die niet meer passen bij de huidige situatie. Wat overblijft in gitflow zijn een paar nuttige branches om integratie te faciliteren: een release‑branch voor stabilisatie en een hotfix‑branch in geval van productie‑noodgevallen. Deze basis werkt goed bij een releasefrequentie van ongeveer eens per drie maanden tot eens per twee weken. Zodra u richting continuous delivery en continuous deployment gaat, merkt u dat zelfs zonder featurebranches de zijwieltjes die u zo geholpen hebben (develop-, release-, hotfix-branch) gaan hinderen. Dat is een ideaal moment om naar github‑flow te bewegen. Tegen die tijd hebt u waarschijnlijk de omvang van elke deploy verkleind: kleinere componenten, beter afgestemde architectuur. Uit ervaring kan ik zeggen dat deze stappen zorgen voor een

Er is dus geen absolute ‘beste’ manier voor versiebeheer. Samengevat met een bekend ontwerpmantra: “It depends”. Niet alle software is meteen klaar voor een low‑inventory werkwijze zoals in de github‑flow. Met gitflow maakt u de transitie eenvoudig, zolang u niet in de valkuil “maak voor echt alles een featurebranch” stapt. Daarom is gitflow een prima manier om te beginnen, mits u het “verantwoord” gebruikt.

Implement DevOps

Implementing DevOps requires linking the support systems to bring the ‘Dev’ to the ‘Ops’ and vice versa.

Find out how to set this up in 30 minutes yourselves.

Go DevOps!