Arribem a l'última lliçó del curs, i la pregunta que toca fer-se és la més honesta que es pot plantejar al final de qualsevol formació tècnica: quant de tot això continuarà sent cert d'aquí a deu anys?

Git ja té dues dècades. Va néixer el 2005 per a un problema molt concret —coordinar el desenvolupament del nucli de Linux quan el seu equip va perdre l'eina que feia servir— i es va convertir en l'estàndard universal del control de versions. Però no està congelat: en surt una versió nova cada pocs mesos, i algunes d'aquestes versions porten canvis profunds que gairebé ningú no fa servir encara.

Aquesta lliçó separa amb cura tres coses que se solen barrejar:

  1. El que ja existeix i pots fer servir avui, encara que sigui poc conegut o estigui marcat com a experimental.
  2. El que és tendència: cap a on apunta la feina, sense dates ni promeses.
  3. El que gairebé amb tota seguretat no canviarà, i que és precisament el que vas aprendre al mòdul 1.

I després tanquem el curs: com continuar aprenent pel teu compte, i una recapitulació del camí complet.

Un avís de mètode abans de començar: en el que segueix no donaré dates per a res que no estigui ja disponible, i quan esmenti una versió de Git ho faré com a referència aproximada. El programari evoluciona i les notes de versió són l'única font fiable. El que sí que et puc donar és el criteri per valorar cada cosa: quin problema resol, en quin estat està i si et convé adoptar-la.

Contingut

  1. Com evoluciona Git i com assabentar-se'n
  2. SHA-256: el substitut de SHA-1
  3. reftable: un format nou per a les referències
  4. Clons parcials i índex dispers
  5. commit-graph i git maintenance
  6. switch i restore enfront de checkout
  7. Taula de maduresa: què fer servir avui
  8. Tendències: cap a on apunta la feina
  9. El paper dels assistents d'IA
  10. El que no canviarà
  11. Com continuar aprenent
  12. El curs complet, recapitulat

  1. Com evoluciona Git i com assabentar-se'n

Git es desenvolupa en obert, per correu, amb el model que vam estudiar a la lliçó 10-01: pedaços en una llista pública, un mantenidor que integra, i publicacions periòdiques cada pocs mesos. Cada versió porta un fitxer de notes que descriu què hi ha de nou, què s'ha corregit i què canvia de comportament.

Saber en quina versió estàs i què porta és el primer hàbit:

git --version
git version 2.51.0

I les notes de cada versió són al repositori mateix de Git, a Documentation/RelNotes/. Llegir les de cada versió nova costa cinc minuts i és la millor manera de descobrir coses que fa anys que fas malament.

Un detall que convé conèixer: Git és extraordinàriament conservador amb la compatibilitat cap enrere. Un repositori creat el 2006 s'obre avui sense conversió, i les ordres que vas aprendre continuen funcionant. Aquesta és una de les raons per les quals les novetats triguen tant a arribar a l'ús comú: s'introdueixen com a opcionals, conviuen anys amb l'anterior, i només es converteixen en el valor per defecte quan tot l'ecosistema està preparat.

Això té una conseqüència pràctica per a tu: gairebé res del que has après deixarà de funcionar. El que pot passar és que apareguin formes millors de fer el mateix.

  1. SHA-256: el substitut de SHA-1

Per què cal

Recorda del mòdul 1 que tot a Git s'identifica pel hash SHA-1 del seu contingut: blobs, arbres, commits i etiquetes. Aquest hash és l'eix del sistema sencer. I SHA-1, com a funció criptogràfica, està trencat: el 2017 es va demostrar públicament que és possible construir dos continguts diferents amb el mateix hash SHA-1 (una col·lisió), amb un cost computacional elevat però assolible.

Convé ser precís sobre què significa això per a Git, perquè s'exagera en totes dues direccions:

Preocupació Realitat
"Git està trencat, qualsevol pot falsificar commits" No. Una col·lisió útil exigeix construir tots dos continguts expressament; no permet fabricar un objecte que coincideixi amb un d'existent que no controles
"SHA-1 a Git és només un identificador, no seguretat" Parcialment cert, però el hash és el que garanteix la integritat i el que signen les signatures de commit (08-05)
"Tant se val, mai no passarà res" És una debilitat coneguda en un sistema que sosté la cadena de subministrament de programari del món

Git no es va quedar quiet. Des de fa anys incorpora detecció de col·lisions: una variant del càlcul de SHA-1 que detecta els patrons característics d'un atac de col·lisió i rebutja l'objecte. Els fitxers de l'atac públic del 2017 són rebutjats per Git.

Però això és un pedaç. La solució de fons és canviar de funció de hash.

Què existeix avui

Git pot crear repositoris amb SHA-256:

git init --object-format=sha256 repositori-nou
cd repositori-nou

echo "hola" > fitxer.txt
git add fitxer.txt
git commit -m "Primer commit"
git log --format=%H
d0e7f5c1b8a4f39e2c6b0d5a7f1e3c9b4d8a2f6e0c5b1a9d3f7e2c8b4a6d0f5e

Seixanta-quatre caràcters hexadecimals en lloc de quaranta. I comprovar-ho:

git rev-parse --show-object-format
sha256

Tot el que has après funciona igual: add, commit, log, branch, merge, rebase, bisect. El model de dades és idèntic; només canvia la funció que calcula els identificadors. És la millor prova que el que vas aprendre a la lliçó 01-04 és el concepte, no l'algorisme concret.

El problema real: la interoperabilitat

Aquí hi ha el motiu que SHA-256 continuï sent experimental i que gairebé ningú no el faci servir:

Un repositori SHA-256 i un de SHA-1 no poden intercanviar objectes.

git clone https://git.exemple.cat/gestor-tasques.git   # repositori SHA-1
cd gestor-tasques
git remote add altre /ruta/al/repositori-sha256
git fetch altre
fatal: the remote uses a different object format than this repository

No hi ha conversió sobre la marxa ni traducció transparent. I això és un problema enorme, perquè tot el món —totes les plataformes d'allotjament, tots els repositoris existents, totes les eines— és en SHA-1.

El pla de fons, llargament dissenyat, contempla repositoris capaços d'operar en tots dos formats alhora, mantenint una taula de correspondències entre el hash SHA-1 i el SHA-256 de cada objecte, de manera que un repositori SHA-256 pugui parlar amb un servidor SHA-1 traduint a la frontera. Aquesta interoperabilitat és la peça que falta, i és una feina considerable.

Què has de fer tu

Res, de moment. SHA-256 és útil per experimentar i per entendre el model, i pot tenir sentit en un entorn tancat que no intercanviï amb ningú. Per a feina real, mentre l'ecosistema sigui en SHA-1, un repositori SHA-256 és una illa.

El que sí que convé és entendre la distinció, perquè és un exemple perfecte de per què el model de dades importa més que els seus detalls: el dia que Git canviï de funció de hash, tu no hauràs de reaprendre res.

  1. reftable: un format nou per a les referències

El problema del format actual

Recorda de la lliçó 03-01: una branca és un fitxer de text amb un hash a dins.

cat .git/refs/heads/main
4f8a2e6c9d3b1a5e7f2c8b0d4a6e9f1c3b5d7a0e

És d'una simplicitat admirable i funciona perfectament a gestor-tasques, amb les seves cinc branques. Quan hi ha moltes referències, Git les compacta en un únic fitxer:

cat .git/packed-refs | head -5
# pack-refs with: peeled fully-peeled sorted
4f8a2e6c9d3b1a5e7f2c8b0d4a6e9f1c3b5d7a0e refs/heads/main
8a1f6c3d4e5b6a7c8d9e0f1a2b3c4d5e6f7a8b9c refs/remotes/origin/main
2e9f4c7b1a8d3e6f0c5b2a9d4e7f1a8c3b6d0e5f refs/tags/v1.3.0

Aquest sistema —fitxers solts més un fitxer compactat— té límits que es noten a gran escala:

Problema Per què passa
Molts fitxers petits Un repositori amb 100.000 referències té fins a 100.000 fitxers; els sistemes de fitxers pateixen
Escriptures costoses Actualitzar una referència amb packed-refs obliga a reescriure el fitxer sencer
Concurrència limitada Dos processos actualitzant referències alhora competeixen per bloqueigs
Col·lisions de noms No poden coexistir refs/heads/funcio i refs/heads/funcio/nova: un directori no pot ser també un fitxer
Sense historial de referències El reflog és un mecanisme a part, amb el seu propi format
Majúscules i minúscules En sistemes de fitxers que no les distingeixen, Main i main xoquen

Aquest quart punt és el que probablement ja has patit:

git branch funcio
git branch funcio/nova
fatal: cannot lock ref 'refs/heads/funcio/nova': 'refs/heads/funcio' exists;
cannot create 'refs/heads/funcio/nova'

No és una regla arbitrària de Git: és que el sistema de fitxers no permet que funcio sigui alhora fitxer i directori.

Què és reftable

reftable és un format binari per emmagatzemar referències i el seu reflog en un conjunt petit de fitxers ordenats, dissenyat originalment per a servidors amb quantitats enormes de referències i posteriorment incorporat a Git.

Les seves propietats:

  • Cerca binària sobre dades ordenades i comprimides per prefix: trobar una referència entre centenars de milers és immediat.
  • Escriptures per addició, amb compactació periòdica: actualitzar no obliga a reescriure-ho tot.
  • Transaccions atòmiques sobre múltiples referències.
  • Reflog integrat en el mateix format.
  • Sense restriccions del sistema de fitxers: funcio i funcio/nova poden coexistir, i les majúscules es distingeixen sempre.

Es fa servir així:

git init --ref-format=reftable repositori-nou
cd repositori-nou
git rev-parse --show-ref-format
reftable

I aleshores:

ls .git/reftable/
0x000000000001-0x000000000003-a1b2c3d4.ref
tables.list

No hi ha refs/heads/. No hi ha packed-refs. Les referències viuen dins d'aquests fitxers binaris.

Totes les ordres que coneixes funcionen exactament igual. git branch, git tag, git switch, git log, git reflog. L'única cosa que canvia és que ja no pots fer cat .git/refs/heads/main, i has de fer servir la lampisteria (lliçó 09-06):

git for-each-ref --format='%(refname) %(objectname)'
git show-ref
git rev-parse main

Que és, per cert, el que sempre hauries hagut de fer: llegir els fitxers interns a mà mai no va ser una interfície estable. Aquesta és una lliçó pràctica que va més enllà de reftable: fes servir les ordres, no els fitxers.

Estat i recomanació

reftable està disponible en versions recents de Git i es considera funcional, però no és el format per defecte i cal comptar que les eines externes que llegeixin .git/refs/ directament no hi funcionaran.

Què has de fer tu: conèixer-lo i no adoptar-lo encara llevat que tinguis un repositori amb desenes de milers de referències i n'estiguis patint. És un exemple excel·lent d'evolució ben feta: canvia la implementació per complet sense canviar ni una sola ordre.

  1. Clons parcials i índex dispers

Aquests ja els coneixes de la lliçó 10-04, i aquí van amb l'etiqueta que els correspon en aquesta lliçó: són present, no futur.

git clone --filter=blob:none https://git.exemple.cat/projecte.git
git sparse-checkout init --cone --sparse-index
git sparse-checkout set serveis/tasques

Totes dues tècniques estan disponibles, suportades per les plataformes principals i en ús en producció a organitzacions grans. El que és interessant des de la perspectiva d'aquesta lliçó és què representen: són la resposta de Git a un problema que el seu disseny original no contemplava.

Git va néixer amb un supòsit implícit: cada clon té el repositori complet. Això és el que el fa distribuït i el que li dona la seva resistència (lliçó 09-05: qualsevol clon és una còpia de seguretat). Però també és el que el feia inviable per a repositoris de desenes de gigabytes.

Els clons parcials relaxen aquest supòsit sense trencar el model: el repositori continua tenint el graf complet i continua sabent quins objectes existeixen; simplement alguns no estan descarregats encara i es demanen quan calen. És una solució elegant perquè conserva la semàntica i només difereix la transferència.

La tendència que representen és clara: Git evoluciona cap a poder treballar amb repositoris de qualsevol mida sense renunciar al seu model. És previsible que aquesta feina continuï: millor gestió de què es descarrega, millors heurístiques de prefetch i menys casos rars.

  1. commit-graph i git maintenance

També present, també de la lliçó 10-04 i la 08-06.

git config --global core.commitGraph true
git config --global fetch.writeCommitGraph true
git maintenance start

Representen una altra línia d'evolució: estructures auxiliars que acceleren sense canviar el model. El commit-graph no és informació nova: és informació que ja era als objectes commit, precalculada en un format que es llegeix ràpid. Si l'esborres, no perds res; es regenera.

Aquest principi de disseny —memòries cau derivades, regenerables i opcionals— és molt sa i és previsible que s'estengui. És la manera de millorar el rendiment sense comprometre la simplicitat del format d'emmagatzematge, que és l'actiu més valuós de Git.

git maintenance, per la seva banda, reflecteix un canvi de filosofia en el manteniment: en lloc que gc t'interrompi quan menys et convé, hi ha tasques programades que s'executen en segon pla. És previsible que acabi sent el comportament per defecte.

  1. switch i restore enfront de checkout

Un cas diferent: no és rendiment ni criptografia, és disseny de la interfície.

git checkout és l'ordre més sobrecarregada de Git. Fa coses conceptualment diferents segons els seus arguments:

git checkout main                    # canviar de branca
git checkout -b nova                 # crear branca i canviar
git checkout 4f8a2e6                 # anar a un commit (HEAD desacoblat)
git checkout -- app.js               # DESCARTAR canvis en un fitxer
git checkout main -- app.js          # portar un fitxer d'una altra branca
git checkout --ours app.js           # resoldre un conflicte

Sis operacions diferents, i una d'elles —la quarta— destrueix feina sense recuperació possible. Que git checkout main (inofensiu) i git checkout -- app.js (irreversible) siguin la mateixa ordre separats per dos guions és un problema de disseny, i ha costat disgustos a molta gent.

La solució va ser partir-la en dues ordres amb propòsits clars:

Abans Ara Què fa
git checkout main git switch main Canviar de branca
git checkout -b nova git switch -c nova Crear branca i canviar
git checkout 4f8a2e6 git switch --detach 4f8a2e6 HEAD desacoblat, de manera explícita
git checkout - git switch - Tornar a la branca anterior
git checkout -- app.js git restore app.js Descartar canvis del disc
git checkout HEAD -- app.js git restore --source=HEAD app.js Restaurar des d'una revisió
git reset HEAD app.js git restore --staged app.js Treure de l'índex
git checkout --ours app.js git restore --ours app.js Resoldre un conflicte

Fixa't en la fila del HEAD desacoblat: amb switch cal demanar-lo explícitament amb --detach. S'ha acabat el "he fet checkout d'una etiqueta i ara soc en un lloc estrany" que vam estudiar a la lliçó 03-02.

I fixa't en la penúltima fila: git restore --staged substitueix un ús de git reset que confonia tothom, perquè reset és una ordre que mou branques (lliçó 09-02) i fer-la servir per treure un fitxer de l'índex barrejava dos conceptes.

Estat

switch i restore fa anys que estan disponibles, van estar marcats com a experimentals durant bastant temps i en versions recents s'han consolidat. Es poden fer servir amb confiança.

I checkout no desapareixerà. Hi ha milions de guions, tutorials i hàbits que en depenen, i Git és conservador amb la compatibilitat. Conviuran indefinidament.

Què has de fer tu: fer servir switch i restore en la teva feina diària, i saber llegir checkout perquè te'l trobaràs en tota la documentació existent, en les respostes d'internet i en els guions de la teva empresa. És exactament la recomanació que vam fer a la lliçó 03-02, i aquí es confirma.

  1. Taula de maduresa: què fer servir avui

Resum operatiu de tot l'anterior, més el que ja coneixes:

Novetat Estat Adoptar-ho avui? Motiu
switch / restore Consolidat Sí, sempre Més clar i més segur que checkout; sense risc
commit-graph Estable Sí, sempre Memòria cau regenerable, sense inconvenients, gran millora en historials grans
git maintenance Estable en repositoris mitjans i grans Manteniment en segon pla en lloc d'interrupcions
fsmonitor / untrackedCache Estable si git status triga Mesura abans; en repositoris petits no aporta
Clons parcials (--filter=blob:none) Estable, suport ampli en repositoris grans i a la CI Historial complet amb una fracció de la descàrrega
sparse-checkout --cone + índex dispers Estable Només en monorepos amb moltíssims fitxers Afegeix confusió si no cal
Git LFS Madur (extern a Git) si hi ha binaris grans que canvien Amb les limitacions de la 10-03
reftable Disponible, no per defecte No llevat de desenes de milers de referències Les eines externes poden no suportar-lo
SHA-256 Experimental No per a feina real Sense interoperabilitat amb l'ecosistema SHA-1

La columna que importa és la tercera, i el seu patró: el que no té inconvenients, adopta-ho ja; el que té cost de comprensió, només si mesures que et cal; el que encara no interopera, coneix-ho i espera.

  1. Tendències: cap a on apunta la feina

Aquí sortim del que és comprovable. El que segueix són direccions observables en l'ecosistema, no prediccions amb data.

Millor experiència per a monorepos

És la línia de treball més visible dels últims anys, i tot el que vam veure a la lliçó 10-04 en forma part: clons parcials, índex dispers, fsmonitor, commit-graph. La motivació és clara: les organitzacions grans han apostat per repositoris enormes, i necessiten que Git hi funcioni.

És raonable esperar-ne més en aquesta direcció: menys casos rars amb sparse-checkout, millors heurístiques sobre què descarregar, i potser que algunes d'aquestes opcions deixin de ser-ho i passin a ser el comportament per defecte quan Git detecti que li convé.

Servidors Git especialitzats

Una dada que convé tenir present: el git que executa un servidor gran no sempre és el git que tens tu. Les plataformes de gran escala han desenvolupat implementacions pròpies del costat del servidor —de vegades basades en Git, de vegades reescriptures compatibles amb el protocol— optimitzades per servir milers de clients concurrents.

Per a tu, això és transparent: parles el protocol de Git i no saps què hi ha a l'altra banda. Però explica per què algunes plataformes suporten funcions que unes altres no, i per què les quotes i els comportaments difereixen (una cosa que ja vam notar amb LFS a la lliçó 10-03).

La tendència és que aquesta especialització augmenti, i que el Git que executes al teu portàtil i el que corre en un servidor siguin cada cop més diferents per dins, encara que parlin el mateix.

Eines construïdes sobre Git, no substituts

Aquest és un patró de vint anys que no dona senyals de canviar. Han aparegut desenes de sistemes de control de versions nous, i alguns són tècnicament interessants. Però el que ha triomfat no són els substituts, sinó les capes construïdes a sobre: plataformes d'allotjament, sistemes de revisió, interfícies gràfiques, eines de gestió de pedaços, sistemes de desplegament (lliçó 10-05), i clients alternatius amb models de treball diferents que emmagatzemen en el format de Git.

La raó és l'efecte de xarxa combinat amb una propietat tècnica: el format d'emmagatzematge de Git és simple, està documentat i és estable. Qualsevol pot escriure una eina que el llegeixi i l'escrigui. Això converteix Git en una cosa semblant a un format de fitxer universal, i substituir un format universal és moltíssim més difícil que substituir un programa.

La conseqüència pràctica per a tu és tranquil·litzadora: encara que la interfície que facis servir canviï, el model de sota probablement no.

Millor experiència de línia d'ordres

Hi ha un corrent sostingut de millora en els missatges d'error i en els suggeriments. Git ha passat de missatges críptics a missatges que expliquen què fer:

git branch -d GT-231-filtre-ocultes
error: the branch 'GT-231-filtre-ocultes' is not fully merged.
hint: If you are sure you want to delete it, run 'git branch -D GT-231-filtre-ocultes'.

Aquesta línia hint: no existia fa anys. És una feina poc espectacular i molt valuosa, i és previsible que continuï.

  1. El paper dels assistents d'IA

Mereix un apartat propi perquè és la novetat més visible de l'ecosistema i la que més confusió genera. Ho mirarem amb el mateix criteri que hem aplicat a tota la resta: què aporta de debò i on és el risc.

On ajuden realment

Redactar missatges de commit. Un assistent pot llegir un diff i proposar un missatge. Funciona bé per a la primera línia —resumir què ha canviat— i és un bon punt de partida quan estàs en blanc.

Explicar codi aliè o un diff gran. Posar en paraules què fa un canvi de 400 línies estalvia temps real durant una revisió.

Recordar ordres i opcions. "Com era l'ordre per veure qui va escriure cada línia ignorant els canvis d'espaiat?" és exactament el tipus de pregunta que un assistent respon bé.

Primera passada de revisió. Detectar patrons sospitosos, oblits evidents, incoherències. Com a comprovació informativa, en el sentit de la lliçó 10-02: que informi, no que bloquegi.

Generar guions auxiliars. Els guions de les lliçons 10-05 i 10-04 són exactament el tipus de cosa que un assistent escriu amb soltesa.

On no ajuden, i el risc

El perquè del canvi no és al diff. I el perquè és el que importa d'un missatge de commit (lliçó 08-01). Un assistent pot escriure perfectament "afegeix el filtre de tasques ocultes al llistat" llegint el codi. El que no pot escriure és:

El comptador ha de continuar incloent-les perquè l'especificació de
GT-231 diu que "pendents" compta totes les tasques no completades,
siguin visibles o no.

Aquest paràgraf —el mateix de la lliçó 09-06— conté una decisió, un motiu i una referència a una discussió. És al teu cap, no al codi. Un missatge generat automàticament que descriu el què i omet el perquè és un missatge que ha perdut la seva funció.

Un missatge generat i no revisat és pitjor que cap, perquè sembla documentació i no ho és. I l'historial és l'únic document del projecte que ningú no pot editar després.

El risc de fons: acceptar sense entendre. És el mateix risc del botó "Sincronitzar" de la lliçó 10-02, amplificat. Si un assistent et proposa git reset --hard HEAD~3 i l'executes sense entendre'l, el problema no és l'assistent: és que estàs executant operacions destructives a cegues.

I hi ha una asimetria molt concreta que convé tenir present: les operacions de Git no són igual de reversibles. Un suggeriment equivocat de git log no costa res. Un suggeriment equivocat de git push --force, git reset --hard o git clean -fd pot costar feina que no es recupera. Com més destructiva és l'operació, més exigeix entendre-la abans.

El criteri

Un assistent ajuda a redactar, a recordar i a explorar. No eximeix d'entendre el canvi.

I una regla pràctica derivada de tot el curs:

Tasca Delegar-ho a l'assistent Per què
Redactar l'assumpte d'un commit , revisant-ho El què és al diff
Escriure el cos que explica el perquè No Només tu ho saps
Recordar la sintaxi d'una ordre És documentació
Executar una operació destructiva suggerida No sense entendre-la reset --hard, push --force, clean -fd
Explicar un diff aliè Estalvia temps real
Decidir si un canvi és bona idea No Requereix context del producte
Generar un guió auxiliar , llegint-lo I provant-lo en un repositori de proves
Resoldre un conflicte de fusió Amb molta cautela Requereix entendre les dues intencions (03-05)

Fixa't que aquesta taula és la mateixa de la lliçó 10-02 sobre interfícies gràfiques, amb altres noms. La regla de fons no ha canviat en tot el mòdul: automatitza el que és repetitiu, entén el que és irreversible.

I hi ha una conseqüència optimista: en un món on escriure codi costa menys, entendre l'historial, saber per què es va prendre una decisió i poder recuperar-se d'un error valen més, no menys. Just el que ensenya aquest curs.

  1. El que no canviarà

Després de mirar el que es mou, toca mirar el que no. I això és el més important de la lliçó.

El model de dades adreçable per contingut

Tot objecte s'identifica pel hash del seu contingut. El hash pot canviar de SHA-1 a SHA-256; la idea, no. I d'ella se'n deriven, com a conseqüències necessàries, propietats que has fet servir durant tot el curs:

  • Els objectes són immutables: canviar el contingut produeix un objecte diferent.
  • El contingut idèntic es guarda una sola vegada, en qualsevol branca i en qualsevol moment.
  • El hash d'un commit verifica tot el seu historial, perquè inclou el del seu arbre i el dels seus pares.
  • Reescriure història crea objectes nous; no modifica els vells. Per això el reflog pot recuperar-los (09-04).

Aquest últim punt és la clau de mig curs. rebase, amend, cherry-pick, filter-repo: tots creen objectes nous i mouen referències. Els originals continuen allà fins que la recollida d'escombraries els esborra. Això no és una característica afegida: és una conseqüència matemàtica de l'adreçament per contingut.

El graf dirigit acíclic de commits

Cada commit apunta als seus pares. D'aquí surten les branques, les fusions, els ancestres comuns i tota la resta:

  • Una branca és un punter mòbil a un node (03-01).
  • Una fusió és un commit amb dos pares, i la base és l'ancestre comú (03-03).
  • bisect és cerca binària sobre el graf (06-02).
  • rebase és reproduir un camí sobre un altre punt (05-01).
  • Una divergència és que dues referències apunten a nodes sense relació d'avantpassat (09-03).
  • merge-base --is-ancestor és una pregunta sobre accessibilitat, i és el que fèiem servir per verificar desplegaments (10-05).

Aquest graf no canviarà. És massa simple, massa potent i massa central.

La naturalesa distribuïda

Cada clon és un repositori complet, amb tot l'historial i tota la capacitat d'operar sense connexió. D'aquí surten:

  • Que puguis treballar sense xarxa i sincronitzar després (04-04).
  • Que qualsevol clon sigui una còpia de seguretat viable (09-05).
  • Que no existeixi un repositori "oficial" llevat que hi hagi acord (04-01).
  • Que els forks funcionin (07-01) i que el model del nucli sigui possible (10-01).

Els clons parcials relaxen el "complet" per al contingut, però no el model: continues tenint el graf sencer i continues sent autònom per a gairebé tot.

Les tres zones

Còpia de treball, índex i repositori (lliçó 01-03). L'índex és la peça que més desconcerta al principi i la que més valor dona després: és el que permet add -p (02-04), el que fa que git add sigui també una xarxa de seguretat, i el que sosté la resolució de conflictes amb les seves tres etapes (03-05).

Per això aquest curs no caduca

Has après ordres, però sobretot has après un model. Les ordres canviaran de nom —checkout s'ha partit en switch i restore— i apareixeran opcions noves. El model fa vint anys que és idèntic i no hi ha cap senyal que vagi a moure's.

Quan d'aquí a cinc anys et trobis una ordre que no coneixes, la pregunta que et permetrà entendre-la en trenta segons serà sempre la mateixa: quins objectes crea i quines referències mou?

  1. Com continuar aprenent

Acabat el curs, la millor manera de continuar és fent servir el que Git ja porta.

La documentació integrada

# Manual complet d'una ordre
git help rebase
git rebase --help

# Resum ràpid d'opcions, sense obrir el manual
git rebase -h

# La llista de TOTES les guies conceptuals
git help -g

Aquest git help -g és un descobriment per a molta gent. Retorna una llista de guies que no són manuals d'ordres sinó explicacions de conceptes:

Guia De què tracta Quan llegir-la
gitcore-tutorial Git des de la lampisteria: com es construeixen els objectes a mà La millor de totes. Llegeix-la ja
giteveryday Les ~20 ordres que cobreixen el 99 % de l'ús, per rol Com a repàs ordenat
gitglossary Definicions precises de tota la terminologia Quan dubtis d'un terme
gitworkflows Com treballa el projecte Git mateix amb les seves branques Complement del mòdul 7
gitrevisions La sintaxi completa de HEAD~3, main@{2}, A...B Després del mòdul 2
gittutorial Introducció bàsica Ja la vas superar
gitcvs-migration Migrar des de sistemes centralitzats Si et toca
git help gitcore-tutorial
git help giteveryday
git help gitrevisions

Comença per gitcore-tutorial. Construeix un repositori des de zero fent servir només ordres de lampisteria: hash-object, update-index, write-tree, commit-tree. Després d'aquest curs, aquesta guia et resultarà llegible i consolidarà el model mental com cap altra cosa.

Les notes de versió

Cada versió nova de Git porta un fitxer de notes. Llegir-les quan actualitzis és l'hàbit amb millor retorn per mantenir-te al dia. És on descobriràs l'opció que fa anys que trobes a faltar i que existeix des de fa tres versions.

Practicar la lampisteria en un repositori de proves

Això és el que més consolida. Crea un repositori d'usar i llençar i construeix un commit sense fer servir git commit:

mkdir /tmp/laboratori && cd /tmp/laboratori && git init

# 1. Crear un blob a partir de contingut
echo "Hola des de la lampisteria" | git hash-object -w --stdin
9f8c2e1a4b7d0f3c6e9b2a5d8f1c4e7a0b3d6f9c
# 2. Ficar-lo a l'índex amb un nom
git update-index --add --cacheinfo 100644,9f8c2e1a4b7d0f3c6e9b2a5d8f1c4e7a0b3d6f9c,salutacio.txt

# 3. Convertir l'índex en un objecte arbre
git write-tree
2a4c8e0f1b3d6a9c2e5f8b1d4a7c0e3f6b9d2a5c
# 4. Crear un commit que apunti a aquell arbre
echo "El meu primer commit fet a mà" | git commit-tree 2a4c8e0f1b3d6a9c2e5f8b1d4a7c0e3f6b9d2a5c
7e1b4d9a2c5f8b0e3d6a9c2f5b8e1d4a7c0f3b6d
# 5. Apuntar la branca a aquell commit
git update-ref refs/heads/main 7e1b4d9a2c5f8b0e3d6a9c2f5b8e1d4a7c0f3b6d

# 6. Comprovar que Git el veu com un repositori normal
git log --stat
git status

Acabes de fer a mà el que git commit fa per tu. Blob → índex → arbre → commit → referència. És el model de la lliçó 01-04 executat pas a pas, i és l'exercici que separa qui fa servir Git de qui l'entén.

Llegir l'historial de projectes aliens

Com vam veure a la lliçó 10-01: clona un projecte que admiris amb --filter=blob:none i mira com treballa. Com escriuen els missatges, si l'historial és lineal, qui integra, com estructuren les sèries de commits. S'aprèn moltíssim.

Ensenyar-ho

El millor filtre per saber si has entès una cosa és explicar-la a algú. Quan un company s'encalli amb una divergència o perdi un commit, ajuda'l explicant el model, no només donant l'ordre. Si ets capaç de dibuixar el graf en una pissarra i assenyalar on era el commit perdut, ho has entès.

  1. El curs complet, recapitulat

Tanquem mirant el camí sencer.

D'on vas partir

Vas començar sense saber què és un repositori. Sense saber quina diferència hi ha entre desar una còpia d'una carpeta i versionar un projecte. Deu mòduls després:

flowchart TD
    M1["1. Entendre<br/>Model de dades, tres zones,<br/>hash del contingut"]
    M2["2. Construir història<br/>add, commit, diff, log"]
    M3["3. Ramificar<br/>branques, merge, conflictes"]
    M4["4. Col·laborar<br/>remots, fetch, push, seguiment"]
    M5["5. Manipular<br/>rebase, cherry-pick, tags, revert"]
    M6["6. Eines<br/>hooks, bisect, blame, submòduls"]
    M7["7. Procés<br/>PRs, revisions, fluxos, CI"]
    M8["8. Ofici<br/>missatges, historial net,<br/>seguretat, rendiment"]
    M9["9. Rescatar<br/>reset, reflog, corrupció,<br/>depuració"]
    M10["10. Operar<br/>casos reals, LFS, escala,<br/>DevOps, futur"]

    M1 --> M2 --> M3 --> M4 --> M5 --> M6 --> M7 --> M8 --> M9 --> M10

Els deu mòduls, en una línia cadascun

Mòdul Què te'n portes
1. Introducció Que Git és una base de dades d'objectes adreçats per contingut, no una eina que desa diferències. Blob, arbre, commit, etiqueta; les tres zones; el hash que ho verifica tot
2. Operacions bàsiques El cicle editar → preparar → confirmar, i que git add -p i git diff --staged converteixen confirmar en un acte deliberat
3. Branques i fusió Que una branca és un punter mòbil i que fusionar és trobar l'ancestre comú. Que un conflicte no és un error: és una decisió que Git no pot prendre per tu
4. Remots Que no hi ha servidor central llevat que hi hagi acord, i que fetch i pull són operacions diferents. Autenticació, refspecs, branques de seguiment
5. Operacions avançades Que la història es pot reescriure abans de publicar-la, i la regla d'or: mai després. rebase, cherry-pick, stash, etiquetes anotades amb SemVer, revert
6. Eines Que Git porta respostes per a "quan es va trencar?" (bisect) i "per què és així?" (blame + el missatge). Hooks, àlies, submòduls, worktree
7. Col·laboració Que el procés importa tant com les ordres: propostes, revisió, fluxos comparats i integració contínua. I que el flux es tria segons l'equip
8. Bones pràctiques L'ofici: missatges que expliquen el perquè, historial llegible, .gitignore i .gitattributes, secrets fora, i mesurar el rendiment abans de tocar
9. Solució de problemes Que a Git gairebé res no es perd de debò. reset, divergències, reflog, fsck --lost-found, bundle, i un mètode de depuració amb GIT_TRACE i lampisteria
10. Món real Que Git és una peça d'un ecosistema: casos reals, integració amb eines, LFS, escalat, DevOps. I criteri per triar

Les quatre idees que ho sostenen tot

Si d'aquí a cinc anys només recordes quatre coses d'aquest curs, que siguin aquestes:

1. El hash del contingut. Tot objecte s'identifica pel hash del que conté. D'aquí surten la immutabilitat, la verificació d'integritat, la desduplicació automàtica i el fet que reescriure història sempre creï objectes nous en lloc de modificar els existents.

2. El DAG de commits. Cada commit apunta als seus pares. Branques, fusions, ancestres comuns, bisect, rebase, divergències: tot és aquest graf mirat des d'angles diferents. Quan alguna cosa no quadri, dibuixa el graf.

3. Les tres zones. Còpia de treball, índex i repositori. Saber en quina de les tres és cada cosa explica el 90 % de les confusions. I recorda l'asimetria que vam descobrir a la lliçó 10-02: el que mai no ha passat per git add és l'única cosa veritablement irrecuperable.

4. La regla d'or. Reescriu la història que no has publicat; no reescriguis la que altres ja tenen. I quan calgui fer-ho —una migració a LFS, una neteja de secrets—, avisa, coordina i fes servir --force-with-lease.

I una cinquena, que és d'actitud

Gairebé res no es perd de debò. El que es perd és la calma. Davant d'un embolic, la seqüència és sempre la mateixa: git status per saber on ets, git log --oneline --graph per veure la forma del problema, git reflog per saber per on has passat. I no executar res destructiu fins a entendre la situació.

gestor-tasques va ser només l'excusa

Ana Ferrer a Ubuntu, Bruno Salas a macOS, Carla Vidal a Windows 11 i Diego Rueda amb el seu fork porten deu mòduls resolent problemes: el submòdul components-ui, els finals de línia que trencaven les diferències, la contrasenya que feia mesos que era a l'historial, el reset --hard a les onze de la nit, els tiquets GT-NNN que lliguen cada commit al seu perquè.

Res d'això no importa. gestor-tasques no existeix. El que existeix és el model mental que t'has construït resolent els seus problemes.

El dia que arribis a un repositori amb vint anys d'història, cinquanta mil fitxers, un flux que no havies vist i una convenció de commits que et semblarà rara, no reconeixeràs res. Però sabràs preguntar:

  • Quina forma té aquest graf? → git log --oneline --graph --all
  • Com treballa aquest equip? → git log --format=%s -40, git rev-list --count --merges HEAD
  • Qui integra de debò? → git log --format='%cn' -300 | sort | uniq -c | sort -rn
  • Per què aquesta línia és així? → git blame -w -M i el missatge del commit
  • Quan es va trencar? → git bisect
  • On soc i com hi he arribat? → git status, git reflog
  • Què hi ha desplegat? → git merge-base --is-ancestor, git describe

Aquestes preguntes funcionen en qualsevol repositori del món. Això és el que te'n portes.

Errors Habituals i Consells

Error 1: adoptar el que és experimental en producció. SHA-256 sense interoperabilitat converteix el teu repositori en una illa. reftable pot trencar eines externes. Distingeix sempre entre "existeix" i "és adoptable".

Error 2: creure que el model de dades canviarà. No canviarà. La funció de hash pot canviar; l'adreçament per contingut, el DAG i les tres zones, no. No deixis d'aprendre'ls "per si de cas queden obsolets".

Error 3: quedar-se a checkout per costum. switch i restore són més clars i més segurs, i separen operacions inofensives d'operacions destructives. Canvia-hi; i aprèn a llegir checkout perquè és a tota la documentació existent.

Error 4: acceptar missatges de commit generats sense revisar-los. L'assistent veu el diff, no el teu cap. El perquè només el pots escriure tu, i és l'única cosa que aporta valor d'aquí a sis mesos.

Error 5: executar ordres suggerides sense entendre-les. Especialment reset --hard, push --force, clean -fd i filter-repo. Com menys reversible és una operació, més exigeix entendre-la abans.

Error 6: no llegir mai les notes de versió. És on hi ha l'opció que fa dos anys que trobes a faltar.

Consell 1: fes git help -g ara mateix, i llegeix gitcore-tutorial. Després d'aquest curs et resultarà llegible, i és el que consolida el model mental definitivament.

Consell 2: tingues un repositori de laboratori. /tmp/laboratori, d'usar i llençar. Prova-hi tot el que no tinguis clar abans de fer-ho en un repositori real. Costa cinc segons crear-lo i ha salvat moltes tardes.

Consell 3: activa avui el que no té inconvenients.

git config --global core.commitGraph true
git config --global fetch.writeCommitGraph true
git config --global merge.conflictStyle zdiff3
git config --global rerere.enabled true
git config --global push.default simple
git config --global pull.ff only

Consell 4: quan trobis una ordre nova, pregunta sempre el mateix. Quins objectes crea? Quines referències mou? És reversible? Amb aquestes tres respostes entens qualsevol ordre de Git.

Consell 5: ensenya el que saps. És el millor filtre per descobrir el que et pensaves que entenies i no entenies.

Exercicis

Exercici 1: separar el que és madur del que és experimental

Un company torna d'una conferència i proposa aquests canvis per a gestor-tasques. Per a cadascun, digues si l'adoptaries avui, i per què:

A. Migrar el repositori a SHA-256 "perquè SHA-1 està trencat". B. Canviar el format de referències a reftable "perquè és més ràpid". C. Activar el commit-graph a tots els repositoris de l'equip. D. Clonar sempre amb --filter=blob:none. E. Prohibir git checkout a l'equip i fer servir només switch i restore. F. Activar sparse-checkout perquè cada persona vegi només la seva àrea.

Exercici 2: construir un commit amb lampisteria

En un repositori de proves buit, crea sense fer servir git add ni git commit:

  1. Un fitxer notes.txt amb el contingut Aprenent la lampisteria.
  2. Un segon fitxer README.md amb el contingut # Laboratori.
  3. Un commit que contingui tots dos, amb el missatge Commit construït a mà.
  4. Una branca main que apunti a aquell commit.

Després, verifica amb ordres de porcellana que Git el veu com un repositori normal, i explica què representa cada hash intermedi.

Exercici 3: arribar nou a un repositori desconegut

T'incorpores a un projecte que no coneixes: 340.000 commits, 12 anys d'història, 28.000 fitxers, 4,2 GB. Ningú no té temps d'explicar-te res i la teva primera tasca és corregir un error en un fitxer que no saps quin és.

Escriu la seqüència d'ordres que executaries el teu primer dia, explicant quina pregunta respon cadascuna i en quin ordre ho faries.

Solucions

Solució 1

A. SHA-256 — NO.

El raonament de partida és correcte (SHA-1 té col·lisions demostrades) però la conclusió no ho és avui:

  • No hi ha interoperabilitat: un repositori SHA-256 no pot intercanviar objectes amb git.exemple.cat, ni amb les plataformes, ni amb el fork d'en Diego. gestor-tasques quedaria aïllat.
  • Git ja incorpora detecció de col·lisions, que mitiga l'atac conegut.
  • El risc real per a un repositori d'aplicació és baix: fabricar una col·lisió exigeix construir tots dos continguts expressament.

Què faria: conèixer-lo, crear un repositori de proves amb --object-format=sha256 per veure el model, i esperar que hi hagi interoperabilitat. Si l'equip vol reforçar la integritat avui, la resposta útil és signar els commits i les etiquetes (08-05), que és efectiu i compatible amb tot.

B. reftable — NO.

gestor-tasques té unes poques desenes de referències. reftable resol problemes que apareixen amb desenes de milers: cost d'escriptura, concurrència, límits del sistema de fitxers. Aquí no aportaria res mesurable.

I té un cost: les eines externes que llegeixin .git/refs/ directament poden fallar, i no és el format per defecte.

Què faria: conèixer-lo, i saber que si algun dia treballo en un repositori amb moltíssimes referències, existeix. La pregunta correcta és la de la lliçó 10-04: he mesurat que això fa mal?

C. commit-graph — SÍ, sense dubtar-ho.

És la recomanació més fàcil de totes:

  • És una memòria cau derivada i regenerable: si s'esborra, no es perd res.
  • No canvia el format d'emmagatzematge ni el comportament de cap ordre.
  • Millora log, blame i les consultes d'accessibilitat, i en historials grans moltíssim.
  • No té cap inconvenient conegut.
git config --global core.commitGraph true
git config --global fetch.writeCommitGraph true

A gestor-tasques, amb 412 commits, la millora serà imperceptible. Però és un bon hàbit global i es nota tan bon punt treballis en una cosa gran.

D. --filter=blob:none sempre — DEPÈN, amb matisos.

A gestor-tasques (2 MB): innecessari. I té un cost real: introdueix dependència de la xarxa en operacions que ara són locals. git log -p d'història antiga sense connexió fallaria.

En repositoris grans: sí, clarament.

A la CI: sí, gairebé sempre, combinat amb fetch-depth: 0. És la configuració recomanada de la 10-04.

Què faria: no com a norma universal, sinó com a regla condicionada: "en repositoris de més d'1 GB o a la CI, clon parcial". I documentar-ho.

E. switch i restore — SÍ, amb un matís.

Adoptar-los, sí:

  • git switch separa canviar de branca de descartar fitxers, i aquesta separació evita pèrdues de feina reals.
  • Exigeix --detach explícit per al HEAD desacoblat.
  • git restore --staged substitueix un ús confús de reset.
  • Estan consolidats.

El matís és a "prohibir":

  • La documentació existent, les respostes d'internet i els guions antics són plens de checkout. Prohibir-lo no fa que desaparegui del món.
  • Tothom ha de saber llegir-lo, i entendre que git checkout -- fitxer és destructiu.
  • Els guions existents que funcionen no s'han de reescriure per gust.

Què faria: recomanar-los com a opció per defecte al CONTRIBUTING.md i fer-los servir als exemples interns, sense prohibir res.

F. sparse-checkout — NO, rotundament.

És el pitjor dels sis i per dos motius independents:

  1. gestor-tasques té nou fitxers. No hi ha res a dispersar.
  2. La motivació és equivocada. "Que cadascú vegi només la seva àrea" és un objectiu organitzatiu, no de rendiment. sparse-checkout és una optimització de rendiment, no un mecanisme de control d'accés: qualsevol pot ampliar el seu con amb una ordre, i tot l'historial és al seu disc. Fer-lo servir per a això dona una falsa sensació de separació.
  3. I tindria un cost real: fitxers que "no existeixen", cerques que no troben coses, i confusió permanent.

Què faria: explicar que si de debò cal separar accessos, la resposta són repositoris separats amb permisos (10-04), no una optimització de rendiment mal utilitzada.

Patró de les sis respostes: les que adoptaria (C, E, i D condicionada) no tenen inconvenients o resolen un problema mesurat. Les que no (A, B, F) són experimentals, resolen un problema que no tinc, o s'estan fent servir per a una cosa que no són. És exactament la taula de maduresa de l'apartat 7.

Solució 2

mkdir /tmp/laboratori && cd /tmp/laboratori && git init

Pas 1: crear els blobs.

printf 'Aprenent la lampisteria\n' | git hash-object -w --stdin
c4a8f2e91b6d3a70f5c2e8b14d9a6f0c3b7e2d51
printf '# Laboratori\n' | git hash-object -w --stdin
7f2b9e4c1a8d5f0b3e6c9a2d5f8b1e4c7a0d3f6b

-w escriu l'objecte a la base de dades; sense això només en calcularia el hash. Cada hash és el SHA-1 d'aquell contingut concret (precedit d'una capçalera amb el tipus i la mida). Si dues persones creen el mateix contingut en qualsevol repositori del món, obtenen el mateix hash: això és l'adreçament per contingut.

Comprovar que hi són:

git cat-file -t c4a8f2e9    # blob
git cat-file -s c4a8f2e9    # mida en bytes
git cat-file -p c4a8f2e9    # contingut

Pas 2: construir l'índex.

git update-index --add --cacheinfo 100644,c4a8f2e91b6d3a70f5c2e8b14d9a6f0c3b7e2d51,notes.txt
git update-index --add --cacheinfo 100644,7f2b9e4c1a8d5f0b3e6c9a2d5f8b1e4c7a0d3f6b,README.md

git ls-files --stage
100644 c4a8f2e91b6d3a70f5c2e8b14d9a6f0c3b7e2d51 0	README.md
100644 7f2b9e4c1a8d5f0b3e6c9a2d5f8b1e4c7a0d3f6b 0	notes.txt

100644 és el mode: fitxer normal no executable (100755 seria executable, 040000 un directori, 120000 un enllaç simbòlic). El 0 és l'etapa de l'índex: 0 significa "sense conflicte" (les etapes 1, 2 i 3 són la base, el nostre i el seu durant una fusió, lliçó 03-05).

Fixa't en un detall que sorprèn: els fitxers no són al disc. L'índex els declara, però la còpia de treball és buida. És la prova més contundent que l'índex és una zona independent, no un reflex del disc.

Pas 3: convertir l'índex en un arbre.

git write-tree
5e9c2f8b4a1d7e0c3f6b9a2d5e8c1f4b7a0d3e6c
git cat-file -p 5e9c2f8b
100644 blob 7f2b9e4c1a8d5f0b3e6c9a2d5f8b1e4c7a0d3f6b	README.md
100644 blob c4a8f2e91b6d3a70f5c2e8b14d9a6f0c3b7e2d51	notes.txt

L'arbre és un directori: associa noms a hashos d'objectes. El seu propi hash resumeix tot el seu contingut, i per això comparar dos arbres pel seu hash n'hi ha prou per saber si són idèntics. És exactament la propietat que fa possible l'índex dispers de la lliçó 10-04.

Pas 4: crear el commit.

echo "Commit construït a mà" | git commit-tree 5e9c2f8b4a1d7e0c3f6b9a2d5e8c1f4b7a0d3e6c
b3f7a0c5e2d8b1f4a7c0e3d6b9f2a5c8e1d4b7f0
git cat-file -p b3f7a0c5
tree 5e9c2f8b4a1d7e0c3f6b9a2d5e8c1f4b7a0d3e6c
author Ana Ferrer <[email protected]> 1785926400 +0200
committer Ana Ferrer <[email protected]> 1785926400 +0200

Commit construït a mà

El commit apunta a un arbre (la foto completa del projecte) i hi afegeix metadades. No té línia parent perquè és el commit arrel; si li haguéssim passat -p <hash>, la tindria. Aquesta línia parent és tot el DAG.

Pas 5: apuntar la branca.

git update-ref refs/heads/main b3f7a0c5e2d8b1f4a7c0e3d6b9f2a5c8e1d4b7f0
git symbolic-ref HEAD refs/heads/main

Pas 6: verificar amb porcellana.

git log --stat
commit b3f7a0c5e2d8b1f4a7c0e3d6b9f2a5c8e1d4b7f0 (HEAD -> main)
Author: Ana Ferrer <[email protected]>
Date:   Sat Aug 1 12:00:00 2026 +0200

    Commit construït a mà

 README.md  | 1 +
 notes.txt  | 1 +
 2 files changed, 2 insertions(+)
git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	deleted:    README.md
	deleted:    notes.txt

Aquest deleted és correcte i molt instructiu: els fitxers existeixen al commit i a l'índex, però no al disc, perquè mai no els hi vam escriure. Es materialitzen amb:

git checkout .      # o: git restore .
ls
cat notes.txt

Què representa cada hash:

Hash Objecte Què és
c4a8f2e9 blob El contingut de notes.txt, sense nom ni permisos
7f2b9e4c blob El contingut de README.md
5e9c2f8b tree El directori arrel: noms + modes + hashos dels blobs
b3f7a0c5 commit Un arbre + autor + data + missatge + pares
refs/heads/main referència Un fitxer (o entrada reftable) amb el hash del commit

Això és Git sencer. Quatre tipus d'objecte i una referència. Tota la resta —branques, fusions, rebase, stash, bisect, LFS, GitOps— es construeix a sobre d'això.

Solució 3

L'ordre importa: primer entendre la forma del repositori, després com treballa l'equip, i només al final buscar el fitxer.

# ========== FASE 1: CLONAR SENSE PATIR (10-04) ==========
git clone --filter=blob:none https://git.exemple.cat/projecte.git
cd projecte

git config core.commitGraph true
git config core.fsmonitor true
git config core.untrackedCache true
git commit-graph write --reachable --changed-paths

Per què: 4,2 GB amb clon complet són molts minuts. El clon parcial porta el graf complet —que és el que necessito per investigar— amb una fracció de la descàrrega. I el commit-graph amb --changed-paths és imprescindible: sense ell, git log sobre un fitxer en 340.000 commits serà insofrible.

# ========== FASE 2: LA FORMA DEL REPOSITORI ==========
git rev-list --count --all           # quant historial hi ha?
git ls-files | wc -l                 # quants fitxers?
git count-objects -vH                # quant pesa i per què?
git log -1 --format=%ci              # és viu?
git log --reverse --format=%ci | head -1   # des de quan?

# Quins directoris de primer nivell hi ha?
git ls-tree --name-only HEAD

Per què: aquestes sis ordres donen en un minut el mapa que ningú no té temps d'explicar-te: escala, estructura i si el projecte està actiu.

# ========== FASE 3: COM TREBALLA L'EQUIP ==========
# Historial lineal o amb merges? (lliçó 10-01)
git log --oneline --graph -40
git rev-list --count --merges HEAD
git rev-list --count HEAD

# Quina convenció de missatges fan servir?
git log --format=%s -50

# Qui escriu i qui integra?
git log --format='%an' -500 | sort | uniq -c | sort -rn | head
git log --format='%cn' -500 | sort | uniq -c | sort -rn | head

# Hi ha convencions documentades?
ls CONTRIBUTING.md README.md .editorconfig .gitattributes 2>/dev/null
cat CONTRIBUTING.md 2>/dev/null

# Quines branques hi ha vives?
git branch -r --sort=-committerdate --format='%(refname:short) %(committerdate:relative)' | head -20

# Com versionen?
git tag --sort=-v:refname | head -10
git describe --tags

Per què: abans de tocar res cal saber com es fan les coses aquí. Una proposta que ignora la convenció de missatges o el flux de branques es rebutja, i aprendre-ho de l'historial és més ràpid i més fiable que preguntar.

La proporció de merges i la diferència autor/committer revelen el model de treball (lliçó 10-01). El CONTRIBUTING.md, si existeix, es llegeix sencer.

# ========== FASE 4: PREPARAR L'ENTORN ==========
# Hi ha LFS? (10-03)
cat .gitattributes 2>/dev/null | grep lfs
git lfs install && git lfs ls-files | head

# Hi ha submòduls? (06-05)
cat .gitmodules 2>/dev/null

# Com es compila i es prova?
cat README.md | head -60
ls Makefile package.json Containerfile .github/workflows/ 2>/dev/null

# Àlies útils per a la investigació (06-04)
git config alias.hist "log --graph --oneline --decorate"
git config alias.qui "log --format='%h %an %ar %s'"
# ========== FASE 5: TROBAR EL FITXER DE L'ERROR ==========
# Pel text del missatge d'error que veu l'usuari
git grep -n "L'import no pot ser negatiu"

# Si el missatge és en fitxers de traducció, buscar-ne la clau
git grep -n "error.import.negatiu"

# Per nom aproximat
git ls-files | grep -i import

# S'ha tocat aquella zona últimament?
git log --oneline -20 -- src/facturacio/

Per què: git grep busca al contingut versionat i és molt més ràpid que les eines del sistema perquè només mira el que és a l'índex, ignorant artefactes de compilació i fitxers ignorats.

# ========== FASE 6: ENTENDRE ABANS DE CANVIAR (06-03, 09-06) ==========
# Qui va escriure aquella línia i per què? Ignorant espaiat i moviments
git blame -w -M -C -L 120,145 src/facturacio/validador.js

# El missatge del commit: la intenció
git log -1 --format=%B <hash-que-retorna-blame>

# La història completa d'aquella funció
git log -L :validaImport:src/facturacio/validador.js

# Hi ha commits de reformatatge que embruten el blame?
ls .git-blame-ignore-revs 2>/dev/null

Per què: aquest és el pas que separa una correcció d'un bucle, i és la lliçó de l'exercici final del mòdul 9. Si el comportament és intencionat i està justificat per escrit, canviar-lo sense més trenca alguna cosa que algú va demanar, i d'aquí a dues setmanes tornarà el mateix tiquet en sentit contrari.

# ========== FASE 7: SI L'ERROR ÉS UNA REGRESSIÓ (06-02) ==========
git bisect start
git bisect bad HEAD
git bisect good v3.8.0
git bisect run ./proves/reproduir.sh
git bisect reset
# ========== FASE 8: TREBALLAR SEGONS LES CONVENCIONS ==========
git switch -c corregir-validacio-import origin/main
# ... corregir, amb una prova de regressió ...
git add -p
git commit    # amb el format de missatge que vaig observar a la fase 3
git diff origin/main...HEAD   # revisar-me a mi mateix abans de proposar
git push -u origin corregir-validacio-import

Resum del mètode: clonar sense patir, entendre la forma, entendre el procés, preparar l'entorn, trobar el lloc, entendre la intenció abans de canviar res, i treballar segons les convencions observades.

Cap d'aquestes ordres no és específica d'aquest projecte. Funcionen en qualsevol repositori del món, i aquesta és exactament la capacitat que dona aquest curs.

Conclusió

El que es mou, el que no, i què fer

Ja existeix i ho pots fer servir avui: switch i restore en lloc de checkout; el commit-graph i git maintenance; els clons parcials i l'índex dispers; fsmonitor i untrackedCache; i Git LFS per als binaris. Tot això està madur, i el que no té inconvenients convé activar-ho ja.

Existeix però encara no és adoptable: SHA-256, que resol la debilitat coneguda de SHA-1 però no interopera amb l'ecosistema; i reftable, que substitueix refs/ i packed-refs per un format binari molt millor a gran escala però que encara no és el predeterminat. Coneix-los; no els adoptis encara.

És tendència, sense dates: millor experiència per a monorepos, servidors Git especialitzats que el client no veu, eines construïdes a sobre de Git en lloc de substituir-lo —el patró dominant de vint anys—, i missatges d'error cada cop més útils.

Els assistents d'IA ajuden a redactar, a recordar i a explorar. No eximeixen d'entendre el canvi: el perquè no és al diff, i les operacions destructives exigeixen comprensió abans que suggeriment. En un món on escriure codi costa menys, entendre l'historial i saber recuperar-se d'un error valen més, no menys.

I el que no canviarà és el que vas aprendre al mòdul 1: el model de dades adreçable per contingut, el DAG de commits, la naturalesa distribuïda i les tres zones. La funció de hash pot canviar; les idees, no. Per això aquest curs no caduca.

El final del curs

Vas començar sense saber què és un repositori.

Ara entens que Git és una base de dades d'objectes immutables identificats pel hash del seu contingut, organitzats en un graf dirigit acíclic, replicada sencera a cada clon. Saps construir història amb intenció, ramificar i fusionar, col·laborar amb altres a través d'un servidor, reescriure el que encara no has publicat —i només això—, investigar quan i per què es va trencar una cosa, treballar amb un procés de revisió i integració contínua, escriure missatges que serveixin d'aquí a dos anys, mantenir els secrets fora i el rendiment sota control, sortir de qualsevol embolic fent servir el reflog i la lampisteria, i operar Git en producció amb etiquetes que despleguen i artefactes identificats pel hash del commit.

Sobretot, tens un model mental amb què raonar sobre situacions que aquest curs no ha cobert. Quan et trobis una ordre desconeguda, sabràs preguntar quins objectes crea i quines referències mou. Quan alguna cosa no quadri, sabràs dibuixar el graf. Quan algú entri en pànic, sabràs que gairebé res no es perd de debò.

gestor-tasques va ser només l'excusa. L'Ana, en Bruno, la Carla i en Diego no existeixen, i els seus tiquets GT-NNN tampoc. El que existeix és el que et queda després d'haver resolt els seus problemes: el submòdul que es va desincronitzar, els finals de línia entre tres sistemes operatius, la contrasenya a l'historial, el reset --hard de les onze de la nit, la migració a LFS que va reescriure dos anys de commits.

Aquest és l'equipatge. És transferible a qualsevol repositori, a qualsevol empresa i a qualsevol flux de treball que et trobis, avui i d'aquí a deu anys.

Ara ves a un repositori de debò —el teu, el del teu equip, o el d'un projecte obert que admiris— i fes-lo servir. Executa git log --oneline --graph --all i mira quina forma té. Llegeix git help gitcore-tutorial. Crea un repositori de laboratori a /tmp i trenca coses expressament per practicar el rescat.

I quan un company perdi un commit i se li posi cara de pànic, seu al seu costat, escriu git reflog, i explica-li per què no s'ha perdut res.

Aquí és on es comprova que has après Git.

Dominant Git: De Principiant a Avançat

Mòdul 1: Introducció a Git

Mòdul 2: Operacions Bàsiques de Git

Mòdul 3: Branques i Fusió

Mòdul 4: Treballant amb Repositoris Remots

Mòdul 5: Operacions Avançades de Git

Mòdul 6: Eines i Tècniques de Git

Mòdul 7: Estratègies de Col·laboració i Flux de Treball

Mòdul 8: Bones Pràctiques i Consells de Git

Mòdul 9: Resolució de Problemes i Depuració

Mòdul 10: Git al Món Real

© Copyright 2026. Tots els drets reservats