Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Git en equip

A Workflow Git hem vist com dues persones comparteixen un repositori fent commit directament a main. Per començar és l’enfocament més senzill, però quan l’equip creix, o quan el codi de main s’ha de poder posar en producció en qualsevol moment, cal organitzar-se millor.

Aquest document respon a la pregunta que ve després: com porta un equip els seus canvis a main sense trencar-lo? Farem servir un exemple al llarg de tot el text: un equip de tres persones que desenvolupa una botiga en línia, on a tu et toca afegir la cerca de productes.

El recorregut va de menys a més. Primer, les peces: branques, pull requests, commits fàcils de revisar i rebase. Després, com la indústria combina aquestes peces en fluxos amb nom propi (GitHub flow, trunk-based development, Git flow) i com s’hi connecten els sistemes de CI/CD. Acabarem amb les pràctiques més recents al voltant de la revisió de codi i un punt de partida per al teu propi projecte.

Estratègies de branques

Comencem per una intuïció que treu por a les branques: una branca és només un punter mòbil a un commit, no una còpia dels teus arxius. Crear-la és instantani i pràcticament gratis (git només desa un nom que apunta a un commit), i canviar de branca és moure el HEAD d’un punter a un altre. Quan fas un commit, la branca on ets simplement avança per apuntar al commit nou. Per això treballar amb branques és barat: no dupliques res, només poses etiquetes a punts de la història.

Hi ha dues maneres bàsiques de fer-les servir.

Commit directe a la branca principal

Cada membre fa commits i pushes directament a main. La integració és contínua i el feedback immediat. És el flux que segueix Workflow Git.

# Al principi de la sessió: sincronitzar
git pull origin main

# Treballar, fer commits
git add arxius_modificats
git commit -m "descripció del canvi"
git push origin main

El problema és que no hi ha cap filtre: un error que arriba a main afecta immediatament tot l’equip. Amb dues persones que parlen sovint és assumible. Amb més gent, no.

Feature branches (branques per tasca)

Cada unitat de treball viu en una feature branch, una branca de curta durada amb el nom de la tasca. Per a la cerca de productes, feature/cerca. La branca es fusiona a main quan la tasca és completa i provada.

# Crear una branca per la tasca
git switch -c feature/cerca

# Treballar i fer commits
git add arxius_modificats
git commit -m "descripció del canvi"

# Quan la tasca és llesta, fusionar a main
git switch main
git pull origin main
git merge feature/cerca
git push origin main

# Neteja
git branch -d feature/cerca

Commit directe o feature branches?

Commit directe a mainFeature branches
Complexitat gitBaixaMitjana
Risc de conflictesBaix (si sincronitzen sovint)Mig (si les branques viuen més de 3 dies)
Aïllament del treballCap: un error afecta tothomAlt: els errors queden a la branca
Recomanat per a 1 o 2 personesSí, si no hi ha CI/CDSí, si hi ha CI/CD
Recomanat per a 3 o més personesPossibleSí

Per a equips petits, la resposta depèn de si hi ha tests i desplegaments automàtics (CI/CD); ho veurem a Quan val la pena.

Les branques de curta durada (2 o 3 dies) funcionen bé. Les de llarga durada (més d’una setmana) divergeixen molt de main i els merges es compliquen. La regla pràctica: una tasca, una branca, fusiona ràpid.

Fixa’t, però, que en l’exemple anterior fusiones la teva pròpia branca quan creus que està llesta. Ningú més no mira el codi abans que arribi a main. Aquest és el forat que omplen les pull requests.

Pull requests i merge requests

Una pull request (PR) és una petició per fusionar una branca en una altra, normalment una feature branch a main, que queda oberta perquè l’equip la revisi abans d’acceptar-la. GitHub, Bitbucket, Gitea i Forgejo en diuen pull request; GitLab en diu merge request (MR). És exactament el mateix concepte amb dos noms, i convé reconèixer-los tots dos: els trobaràs constantment en ofertes de feina, documentació i converses d’equip. En aquest document farem servir “PR”.

Una PR agrupa en una sola pàgina web tot el que cal per decidir si un canvi entra:

  • Branca origen i branca destí: què es vol fusionar i on.
  • Descripció: què fa el canvi i per què, escrita per qui el proposa.
  • Diff i llista de commits: què canvia exactament.
  • Comentaris de revisió: converses lligades a línies concretes del codi.
  • Checks de CI: el resultat dels tests i les validacions automàtiques. La integració contínua (continuous integration, CI) és un servei que executa aquestes comprovacions sol cada vegada que puges canvis; en tornarem a parlar a Branques i CI/CD.
  • Aprovacions i botó de merge: la decisió final.

Avui és la pràctica estàndard del treball en equip. La mecànica de fons, però, és independent de la plataforma: primer la veurem amb git pur per entendre què passa realment per sota.

La idea

El principi és senzill: separar qui proposa canvis de qui els accepta. Un desenvolupador treballa a la seva branca i, quan la tasca és llesta, demana a un responsable que revisi i integri els canvis a la branca principal. El responsable pot:

  • Revisar el diff dels canvis proposats.
  • Demanar correccions si cal.
  • Acceptar i fer el merge quan tot és correcte.

Això afegeix una capa de revisió que millora la qualitat del codi i evita que canvis no revisats arribin a la branca principal.

El flux amb git pur

Aquest flux no requereix cap eina especial, només git i una convenció d’equip:

1. Treballes a la teva branca i la puges al repositori remot:

git switch -c feature/cerca
# ... treballa, fa commits ...
git push -u origin feature/cerca

El -u associa la branca local amb la remota (estableix l’upstream), de manera que les properes vegades n’hi ha prou amb git push.

2. Avises el responsable (per correu, xat o qualsevol canal) que la branca està llesta per revisar.

3. El responsable revisa els canvis des del seu repositori local:

git fetch origin
git log --oneline main..origin/feature/cerca   # quins commits hi ha
git diff main..origin/feature/cerca          # què canvien

4. Si cal demanar correccions, el responsable t’ho comunica. Fas els canvis a la mateixa branca, commit i git push (ja no cal especificar el remot ni la branca gràcies al -u inicial), i el responsable torna a revisar.

5. Quan els canvis són acceptats, el responsable fa el merge:

git switch main
git pull origin main
git merge origin/feature/cerca
git push origin main

# Neteja de la branca remota
git push origin --delete feature/cerca

6. Tu sincronitzes i neteges en local:

git switch main
git pull origin main
git branch -d feature/cerca

El mateix flux a la plataforma

Una PR no inventa res de nou: automatitza i deixa per escrit els passos anteriors.

Pas amb git purAmb una PR
1. Pujar la brancaIgual: git push -u origin feature/cerca
2. Avisar el responsableObrir la PR, amb una descripció i els revisors assignats
3. Revisar amb git log i git diffLa plataforma mostra els commits i el diff, i el CI hi executa els tests sol
4. Demanar correccionsComentaris a les línies concretes; cada push a la branca actualitza la PR
5. Fer el mergeBotó de merge, que es pot bloquejar fins que hi hagi aprovacions i el CI passi
6. NetejarLa plataforma pot esborrar la branca remota automàticament; en local, igual que abans

La diferència important no és la comoditat, sinó que la revisió queda registrada: d’aquí a un any, qualsevol persona podrà trobar la PR que va introduir una línia i llegir per què es va fer i què se’n va discutir.

Permisos sobre branques

Per reforçar aquest flux, es poden configurar permisos d’escriptura sobre les branques del repositori remot. Per exemple, restringir l’escriptura a main a un sol usuari o a un grup reduït. D’aquesta manera, els desenvolupadors poden pujar les seves feature branches però no poden fer push directament a main: només s’hi arriba a través d’una PR revisada.

Això converteix una convenció organitzativa en una restricció tècnica. La majoria de servidors git (inclosos els auto-allotjats) permeten configurar aquests permisos. A GitHub i GitLab es fa amb les regles de protecció de branca (branch protection rules), que típicament es configuren per:

  • exigir que els canvis arribin via PR;
  • requerir un nombre mínim d’aprovacions;
  • no permetre el merge fins que els checks de CI passin;
  • prohibir el push forçat, perquè ningú no pugui reescriure la història de main.

Quan val la pena

Per a 1 o 2 persones, un procés formal pot semblar excessiu. Però la mida de l’equip no és el que més pesa: el que decideix si calen branques i PR és si hi ha CI/CD.

  • Sense CI/CD, el commit directe a main és raonable. No s’executa res automàticament i la revisió es pot fer parlant, així que una branca només afegeix passos. És el flux de Workflow Git.
  • Amb CI, la PR és on s’executen els tests abans que el codi arribi a main. Si fas push directe, els tests s’executen quan el codi ja hi és, i si fallen, main queda trencat.
  • Amb CD, on cada canvi a main es desplega, un push directe és un desplegament sense provar, encara que treballis sol.

Si treballes sol, no hi ha ningú que revisi: obres la PR, esperes que el CI passi i la fusiones tu mateix. És el mode Show de Ship / Show / Ask, i costa un minut per tasca. L’excepció és el trunk-based development, que accepta commits directes a main si passes els tests en local abans de pujar; és una opció vàlida, però depèn de la disciplina de cadascú, no d’una comprovació automàtica.

Amb 2 persones, a més, la PR és una manera barata d’estar al corrent del que fa l’altre. A mesura que l’equip creix, les PR passen de recomanables a imprescindibles.

Commits fàcils de revisar

Ara que la teva feina passarà per una revisió, els commits deixen de ser només per a tu: són el que llegirà el revisor. Una PR és tan fàcil de revisar com ho són els seus commits. Les dues pràctiques següents fan que el teu company entengui la teva feina sense haver de preguntar-te res.

Missatges de commit

Un bon missatge de commit permet al teu company entendre el canvi sense llegir el diff. Dues convencions habituals:

Imperatiu simple (mínim de fricció):

git commit -m "add product search endpoint"
git commit -m "fix null check in price filter"
git commit -m "remove unused imports"

Regla: comença amb un verb en imperatiu. Descriu què fa el commit, no el que has fet tu. Menys de 72 caràcters.

Conventional Commits (més estructurat):

git commit -m "feat: add product search endpoint"
git commit -m "fix: handle empty search query"
git commit -m "test: add unit tests for search filters"
git commit -m "docs: update README with search examples"
git commit -m "chore: update dependencies"

Prefixos: feat (nova funcionalitat), fix (correcció), test (tests), docs (documentació), chore (manteniment), refactor (refactorització sense canvi de comportament).

Com que el format és estructurat, les eines el poden llegir: a partir dels commits es pot generar el changelog (la llista de canvis de cada versió) o decidir automàticament el número de la versió següent en el pipeline de CI/CD, que veurem més endavant.

Imperatiu simpleConventional Commits
Fricció d’escripturaBaixaMitjana (cal recordar el prefix)
Llegibilitat del logBonaMolt bona
Compatible amb eines de changelogNoSí

Commits atòmics

Un commit atòmic conté un sol canvi lògic, i el codi ha de funcionar després de cada commit. Això contrasta amb fer un sol commit gran al final del dia amb tots els canvis barrejats.

Per què importa? Quan alguna cosa falla, els commits atòmics fan evident quin canvi ha causat el problema:

# Commit gran: on és el problema?
$ git log --oneline -1
a3f9b12  "add search index, filters, endpoint and tests"

# Commits atòmics: el problema és al segon commit
$ git log --oneline -4
a3f9b12  "add search endpoint"
def5678  "add price and category filters"   ← falla aquí
c72a3f8  "add product search index"
5e8d1a0  "add search service skeleton"

També fan la revisió més fàcil: el revisor pot seguir la PR commit a commit, com una història en capítols, en lloc d’enfrontar-se a un sol diff enorme.

Regla pràctica: fes commit de cada unitat lògica de treball per separat, ajudant-te de l’staging area per triar què hi entra. Si el codi no està llest, utilitza git stash per guardar-lo temporalment sense fer commit.

Maneres de fusionar una PR

Quan la PR s’accepta, què els passa, als teus commits? Les plataformes deixen triar com s’incorporen a main. Els noms són els de GitHub; GitLab ofereix opcions equivalents.

MètodeQuè passa a mainQuan triar-lo
Create a merge commitTots els commits de la branca, més un commit de merge amb dos paresVols conservar la història completa i saber quins commits venien junts
Squash and mergeUn sol commit nou amb tots els canvis de la brancaEls commits de la branca són de feina a mitges (“wip”, “fix typo”); a main en queda un de net per tasca
Rebase and mergeEls commits de la branca, reaplicats un a un sobre main, sense commit de mergeEls commits ja són atòmics i vols una història lineal

És la mateixa distinció entre fast-forward i commit de merge que vam veure a Workflow Git, ara decidida per l’equip. Molts equips fan servir squash per defecte: és el més senzill i deixa main amb un commit per PR, fàcil de revertir si alguna cosa falla. Això no fa inútils els commits atòmics: continuen a la PR, i és allà on han facilitat la revisió.

Rebase per mantenir la branca al dia

Mentre treballes a feature/cerca, main avança amb les PR dels teus dos companys. Abans de demanar la revisió, et convé posar la teva branca al dia, perquè el revisor vegi la teva feina sobre el codi actual. Hi ha dues maneres de fer-ho, merge i rebase, i per triar bé cal entendre-les.

Tant el merge com el rebase combinen feina, però d’una manera molt diferent: el merge conserva les dues històries i les uneix amb un commit nou amb dos pares; el rebase, en canvi, reescriu els teus commits perquè quedin com si els haguessis escrit a sobre d’una altra base.

La intuïció: imagina els teus commits enganxats amb post-it. El merge els deixa on són i hi pinta una línia que els connecta amb l’altra branca. El rebase els despenja, mou la base de la branca fins a un altre punt, i els torna a enganxar a sobre. Com que el resultat són commits “nous” (mateix contingut, hashes diferents), val la regla d’or de reescriure història: només sobre feina que encara no has compartit.

Si vas fent merge de main a la teva branca per estar al dia, deixes una bombolla de merge cada cop (“Merge branch ‘main’ into feature/cerca”) i acabes amb una història enrevessada que costa de revisar. El rebase ho evita:

git switch feature/cerca
git fetch
git rebase origin/main

El resultat és una història lineal i neta, com si haguessis començat la feature ara mateix. Hi ha tres beneficis que es combinen:

  • Revisió neta: el revisor veurà la teva feina com una llista de commits per damunt del main actual, sense soroll de manteniment.
  • Integració primerenca: desenvolupes contra el codi real d’ara, així que si main ha canviat el nom d’una funció, ha modificat una signatura o ha introduït un bug, ho descobreixes immediatament en local i no el dia del merge. Compte: el rebase només resol conflictes textuals; els conflictes semàntics no els detecta, així que cal tornar a passar els tests després del rebase per confirmar que tot encaixa.
  • Conflictes més suaus: la quantitat total no canvia (vénen de tocar les mateixes línies), però l’experiència sí: els resols a poc a poc, amb el context d’un sol commit, i no en un únic xoc gran el dia del merge final. Quan la PR finalment s’integra, el merge a main és un fast-forward net.

Compte: després d’un rebase, els commits són nous. Si ja havies pujat la branca, el següent push caldrà fer-lo amb --force-with-lease. Sobre la teva pròpia feature branch això és acceptable, perquè ningú més no hi treballa. Però si algun company també hi fa commits, parla-hi abans de reescriure-la.

Fluxos de treball de la indústria

Fins aquí hem vist peces soltes: branques de curta durada, PR, protecció de branques, commits fàcils de revisar i rebase. A la pràctica, cada equip les combina en un flux de treball (workflow), un acord sobre quines branques existeixen, qui hi pot escriure i com arriba el codi a producció. Alguns d’aquests acords s’han fet tan populars que tenen nom propi. Martin Fowler, en el seu article de referència sobre branques, distingeix precisament entre els patrons (les peces) i les polítiques que els combinen (aquests fluxos).

Els que convé reconèixer són GitHub flow i trunk-based development, els habituals avui, i Git flow, més antic però encara present en molts projectes i tutorials. Tancarem amb GitLab flow, una variant de GitHub flow per a quan hi ha diversos entorns.

GitHub flow

El GitHub flow el va descriure Scott Chacon, de GitHub, el 2011. Té una sola regla central: tot el que és a main es pot desplegar. No hi ha cap altra branca permanent. Tota la feina es fa en feature branches, i els passos són els que ja has fet amb feature/cerca:

  1. Crear una branca des de main amb un nom descriptiu.
  2. Fer-hi commits i pujar-la sovint.
  3. Obrir una PR quan vols feedback o creus que està llesta.
  4. Atendre els comentaris de revisió amb nous commits a la mateixa branca.
  5. Fer el merge a main quan la PR està aprovada i el CI passa.
  6. Esborrar la branca. Com que main és sempre desplegable, el merge es pot desplegar tot seguit.

Al diagrama, la teva cerca avança en paral·lel amb el login que fa una companya. Cada branca entra a main per la seva PR, i main només rep feina revisada:

gitGraph
    commit id: "inici"
    branch feature/login
    checkout feature/login
    commit id: "formulari"
    commit id: "validació"
    checkout main
    branch feature/cerca
    checkout feature/cerca
    commit id: "cerca"
    checkout main
    merge feature/login id: "PR #12"
    checkout feature/cerca
    commit id: "filtres"
    checkout main
    merge feature/cerca id: "PR #13"

Fixa’t que GitHub flow no és res de nou: és la suma de feature branches, PR, protecció de main i CI. Aquesta senzillesa és precisament el que l’ha fet el flux més estès.

Trunk-based development

En el trunk-based development tothom integra a una sola branca, el trunk (main), com a mínim un cop al dia, i l’equip evita qualsevol altra branca de llarga durada. Es pot fer amb commits directes a main en equips molt petits, però en equips reals sol consistir en branques de molt curta durada (hores, com a molt un parell de dies) que entren via PR darrere d’un CI exigent.

La diferència amb GitHub flow és de grau, no de mecànica: GitHub flow no diu quant ha de durar una branca, i trunk-based development diu que molt poc. Integrar tan sovint fa que els conflictes siguin petits i que el codi de tothom es provi junt constantment, que és la idea de la integració contínua.

Però què passa si la cerca de productes triga dues setmanes i la branca ha de durar un dia? El codi s’integra a main a trossos, desactivat. Els feature flags (interruptors de funcionalitat) permeten tenir a producció codi que encara no s’executa, i activar-lo quan està complet. En parlem a estratègies de desplegament.

El preu és que cal una bona bateria de tests automàtics: sense la xarxa del CI, integrar tan sovint seria temerari.

Git flow

El Git flow el va proposar Vincent Driessen el 2010, i durant anys va ser el model de branques. Fa servir dues branques permanents:

  • main: només conté versions publicades, cadascuna marcada amb un tag.
  • develop: on s’integra la feina per a la propera versió.

I tres tipus de branques de suport:

  • feature/*: surten de develop i hi tornen.
  • release/*: surten de develop quan es prepara una versió; només admeten correccions, i es fusionen a main (amb el tag) i a develop.
  • hotfix/*: surten de main per corregir un error urgent en producció, i es fusionen a main i a develop.
gitGraph
    commit id: "inici"
    branch develop
    checkout develop
    commit id: "base"
    branch feature/cerca
    checkout feature/cerca
    commit id: "cerca"
    checkout develop
    merge feature/cerca
    branch release/1.0
    checkout release/1.0
    commit id: "ajustos 1.0"
    checkout main
    merge release/1.0 tag: "v1.0"
    checkout develop
    merge release/1.0
    checkout main
    branch hotfix/1.0.1
    checkout hotfix/1.0.1
    commit id: "correcció"
    checkout main
    merge hotfix/1.0.1 tag: "v1.0.1"
    checkout develop
    merge hotfix/1.0.1

Git flow encaixa quan el programari es publica en versions explícites i n’has de mantenir més d’una alhora: una aplicació d’escriptori, una llibreria, una app mòbil que passa per la revisió de la botiga. Per a una aplicació web com la botiga en línia, que es pot desplegar diverses vegades al dia, en canvi, és massa pesat. L’autor mateix ho va reconèixer el 2020 en una nota afegida a l’article original: per a equips que fan lliurament continu, recomana un flux més simple com GitHub flow.

GitLab flow

El GitLab flow és una variant de GitHub flow per quan desplegar no és instantani o hi ha diversos entorns. Manté main i les feature branches, i hi afegeix branques d’entorn (per exemple pre-production i production): els canvis sempre flueixen en una sola direcció, de main cap a producció, i cada branca reflecteix el que hi ha desplegat en aquell entorn. Si cal mantenir versions publicades, es fan servir branques de release (una per versió, per exemple v1 i v2) en lloc de les d’entorn.

Quin triar

FluxBranques permanentsFeature branchesQuan es desplegaEncaixa amb
Commit directe a mainmainNo se’n fan servirQuan es vulguiEquips de 2 persones, pràctiques
GitHub flowmainUna per tasca, idealment curtes (el flux no en fixa la durada)Després de cada mergeLa majoria de projectes web i serveis
Trunk-based developmentmainOpcionals i molt curtes: hores, com a molt un parell de diesContínuamentEquips amb CI i tests molt sòlids
GitLab flowmain + branques d’entornUna per tasca, com a GitHub flowEn promocionar a la branca d’entornDiversos entorns o desplegaments amb validació manual
Git flowmain + developSurten de develop i poden durar tot el cicle d’una release (a més, hi ha branques release/* i hotfix/*)En tancar una releaseProgramari amb versions i diverses versions mantingudes

Si no tens cap motiu concret per a una altra cosa, tria GitHub flow: és el que trobaràs a la majoria d’equips, el que les plataformes suporten millor, i el punt de partida natural cap a trunk-based development.

Branques i CI/CD

Ja hem vist que la integració contínua (CI) executa els tests de cada PR. Sovint va acompanyada del desplegament continu (continuous deployment, CD), que posa el codi en producció automàticament. El repositori git esdevé així el punt de connexió amb tots dos. Els conceptes de CI/CD s’expliquen a DevOps; aquí ens interessa la relació amb les branques.

Aquesta relació depèn del flux que hagis triat, perquè el flux decideix quins esdeveniments git signifiquen què:

  • A GitHub flow, obrir una PR vol dir “valida això”, i el merge a main vol dir “desplega-ho”.
  • A Git flow, el merge a develop només valida; el tag a main vol dir “publica aquesta versió”.
  • A GitLab flow, fer merge a la branca production vol dir “desplega a producció”.

Com funciona la connexió

Les plataformes com GitHub i GitLab permeten configurar pipelines (seqüències de passos automàtics) que reaccionen a esdeveniments git:

  • Push a una branca (per exemple, main): pot disparar l’execució de tests, anàlisi de codi o compilació. Si els tests fallen, l’equip rep una notificació.
  • Obertura o actualització d’una PR: executa els tests sobre la branca abans que el merge sigui acceptat. És el que alimenta els checks que veus a la PR.
  • Push d’un tag: pot disparar un desplegament a producció o a un entorn de proves.

Això significa que cada git push té conseqüències més enllà del repositori: pot posar en marxa processos automàtics que afecten tot l’equip o fins i tot els usuaris finals.

Implicacions pràctiques

  • Un push descuidat pot bloquejar el CI per a tot l’equip. Si fas push a main de codi que no compila o que trenca els tests, el pipeline fallarà i ningú no podrà validar els seus canvis fins que es corregeixi. Aquest és el motiu principal per protegir main i entrar-hi només via PR.
  • Els tags són decisions de desplegament. En molts projectes, crear un tag actualitza el producte en producció. Cal crear-los de forma deliberada.
  • Prova en local abans de fer push. Executar els tests localment abans de pujar canvis evita cicles innecessaris de CI i estalvia temps a tot l’equip.
  • L’ordre importa. Si el CI reacciona a tags, cal assegurar-se que el commit ja és a la branca principal abans de crear el tag. L’ordre habitual és: primer git push del commit, després git push del tag.
git push origin main            ← el CI valida el codi
git tag -a v1.0 -m "versió 1"
git push origin v1.0            ← el CI desplega a producció

Configuració del CI/CD

La majoria de plataformes git (GitHub, GitLab, Gitea, etc.) inclouen eines de CI/CD integrades. La configuració es fa típicament mitjançant arxius YAML al propi repositori, on es defineixen quins passos s’executen (tests, compilació, desplegament) i en resposta a quins esdeveniments git (push, tag, PR).

Pràctiques actuals al voltant de les PR

Les PR han resolt el problema de la revisió, però n’han creat de nous: esperes llargues per a una aprovació, PR enormes que ningú no vol revisar, i main trencat per dues PR que per separat eren correctes. Aquestes són les respostes més esteses.

Ship / Show / Ask

No tots els canvis necessiten el mateix nivell de revisió. Ship / Show / Ask, proposat per Rouan Wilsenach, classifica cada canvi en tres categories:

  • Ship (envia): el canvi va directe a main, sense PR. Per a coses trivials: corregir una errada al README o a un comentari.
  • Show (mostra): obres una PR perquè l’equip la vegi, però la fusiones tu mateix quan el CI passa, sense esperar aprovació. La conversa, si n’hi ha, ve després.
  • Ask (pregunta): obres una PR i esperes la revisió abans de fusionar. Per a canvis on no estàs segur de l’enfocament o que toquen parts delicades, com la primera versió de la teva cerca.

La idea de fons és que la revisió és una eina, no un peatge: l’equip decideix en cada cas quanta en cal, en lloc d’aplicar sempre el màxim.

Merge queues

Imagina dues PR que, cadascuna per separat, passen el CI contra main. A la del login, la teva companya canvia el nom d’una funció; a la teva, la cerca afegeix una crida a aquella funció amb el nom antic. Quan es fusionen totes dues, main deixa de compilar: és un conflicte semàntic que cap de les dues PR podia detectar sola.

Una merge queue (cua de merge) ho evita. En lloc de fusionar directament, les PR aprovades entren en una cua, i el sistema prova cadascuna combinada amb main i amb totes les PR que té al davant. Només es fusiona si aquesta combinació passa el CI. GitHub l’anomena merge queue i GitLab, merge trains. És habitual en repositoris amb molts merges al dia, perquè garanteix que main es mantingui sempre en verd, és a dir, amb tots els checks del CI passant.

Stacked PRs

Una PR gran costa de revisar, i una PR que costa de revisar s’eternitza. Però de vegades una funcionalitat necessita molts canvis que depenen els uns dels altres. Les stacked PRs (PR apilades) divideixen el canvi en una cadena de PR petites, on cadascuna parteix de l’anterior en lloc de main: per a la cerca, primer l’índex, a sobre els filtres i a sobre l’endpoint. Cada capa es revisa per separat, i quan totes estan aprovades es fusionen en ordre.

Fa anys que la tècnica existeix amb eines externes, però ha guanyat pes amb l’augment de codi generat amb ajuda d’IA: es produeix més codi del que les persones poden revisar, i trossejar-lo en peces petites és la manera de mantenir la revisió útil. Des de juliol de 2026, GitHub les suporta de manera nativa, en fase de proves pública (public preview).

Per començar

Si has de muntar el flux d’un projecte d’equip, aquest és un punt de partida raonable que pots anar ajustant:

  1. Adopta GitHub flow: main sempre desplegable i una feature branch per tasca.
  2. Protegeix main: només s’hi arriba per PR, amb una aprovació i el CI en verd.
  3. Configura un CI mínim que executi els tests a cada PR.
  4. Fes commits atòmics amb missatges clars, i posa la branca al dia amb rebase abans de demanar revisió.
  5. Mantén les branques curtes: si una tasca s’allarga més de dos o tres dies, divideix-la.

Referències

Last change: , commit: 2bf2334