L'Ana té el seu repositori i en Bruno té el seu clon. A partir d'aquí, tots dos fan exactament el mateix cada dia, desenes de vegades: editen fitxers, decideixen quins canvis agrupar i els registren a l'historial. Aquest cicle de tres passos —editar, preparar, confirmar— és el batec de Git. Tota la resta del curs (branques, fusions, rebase, remots) es construeix a sobre.

Al mòdul 1 vas aprendre la teoria: les tres zones (directori de treball, àrea de preparació i repositori) i els tres estats (modificat, preparat, confirmat). En aquesta lliçó aquesta teoria es posa en moviment. Veurem com un fitxer viatja d'una zona a una altra, quins estats travessa des que Git no el coneix fins que queda confirmat, i com git status t'indica en tot moment exactament on ets.

L'objectiu és que, en acabar, puguis mirar la sortida de git status en qualsevol repositori del món i saber en un segon què està passant i quina és l'ordre següent raonable.

Contingut

  1. El cicle de tres passos
  2. Les tres zones en moviment
  3. El cicle de vida d'un fitxer
  4. git status: la brúixola
  5. git status --short: la forma abreujada i la seva taula de codis
  6. Fitxers que no vols versionar: .gitignore en dos minuts
  7. Una sessió de treball completa de l'Ana, narrada
  8. El cicle a la pràctica diària

  1. El cicle de tres passos

El flux de treball bàsic de Git té aquesta forma:

graph LR
    E["1 · EDITAR<br/>Modifiques fitxers<br/>a la teva carpeta"] --> P["2 · PREPARAR<br/>git add<br/>Tries què hi entra"]
    P --> C["3 · CONFIRMAR<br/>git commit<br/>Es registra per sempre"]
    C -.->|tornem-hi| E

Tres passos, dues ordres. El que desconcerta al principi és el pas intermedi: per què no n'hi ha prou amb "desar els canvis"? Per a què existeix l'àrea de preparació?

La resposta és que separa dues decisions diferents:

  • Editar respon a "què he canviat?". És feina.
  • Preparar respon a "què, de tot el que he canviat, forma una unitat amb sentit?". És criteri.

Imagina que l'Ana passa el matí arreglant una fallada a app.js i, de passada, corregeix una falta d'ortografia al README.md i ajusta un color a estils.css. Són tres coses sense relació entre si. Sense àrea de preparació, tindria dues opcions dolentes: ficar-ho tot en una confirmació remenada, o anar desfent canvis a mà per confirmar-los per separat. Amb l'àrea de preparació, tria: prepara només app.js, confirma, prepara README.md, confirma, i així successivament.

El resultat és un historial on cada confirmació explica una sola cosa. Quan d'aquí a sis mesos algú busqui per què es va trencar l'esborrat de tasques, trobarà una confirmació que parla exactament d'això i no de tres assumptes barrejats.

Aquesta idea —el commit atòmic— és tan important que la desenvolupem a fons a la lliçó següent, Preparant i Confirmant Canvis.

  1. Les tres zones en moviment

Recuperem l'esquema de Terminologia Bàsica de Git, aquesta vegada amb les ordres que mouen la informació d'una zona a una altra:

graph LR
    WT["DIRECTORI<br/>DE TREBALL<br/>Els teus fitxers<br/>al disc"]
    IDX["ÀREA DE<br/>PREPARACIÓ<br/>.git/index<br/>L'esborrany del<br/>pròxim commit"]
    REPO["REPOSITORI<br/>.git/objects<br/>L'historial<br/>permanent"]

    WT -->|git add| IDX
    IDX -->|git commit| REPO
    IDX -->|git restore --staged| WT
    REPO -->|git checkout / git restore --source| WT

Tres regles que convé tenir gravades:

  1. Només es confirma el que està preparat. git commit no mira el directori de treball: fotografia l'àrea de preparació. Un canvi que no hagis preparat no hi entra, per molt desat que estigui al disc.
  2. L'àrea de preparació és un estat, no una cua. No és una llista d'ordres pendents; és una versió completa del projecte. Conté el contingut íntegre de cada fitxer, no "les línies que has afegit".
  3. Les tres zones poden tenir continguts diferents del mateix fitxer alhora. És la font de confusió número u dels principiants, i també la font del poder de Git. Ho veurem en acció a la sessió narrada.

  1. El cicle de vida d'un fitxer

Cada fitxer de la teva carpeta és, en cada moment, en un de quatre estats. Aquest diagrama els recull tots i mostra quina ordre produeix cada transició:

stateDiagram-v2
    [*] --> SenseSeguiment: crees el fitxer
    SenseSeguiment --> Preparat: git add
    Preparat --> SenseModificar: git commit
    SenseModificar --> Modificat: edites el fitxer
    Modificat --> Preparat: git add
    Preparat --> Modificat: edites un altre cop
    Preparat --> SenseSeguiment: git rm --cached
    Modificat --> SenseModificar: git restore
    SenseModificar --> [*]: git rm

    SenseSeguiment: Sense seguiment (untracked)
    SenseModificar: Sense modificar (unmodified)
    Modificat: Modificat (modified)
    Preparat: Preparat (staged)

Vegem els quatre estats un a un:

Estat En anglès Què significa Com el veus a git status
Sense seguiment untracked Git veu el fitxer però no l'ha registrat mai. No forma part del projecte A la secció Untracked files
Sense modificar unmodified Idèntic a l'última confirmació. No hi ha res a fer-hi No apareix: Git només informa del que canvia
Modificat modified Ha canviat respecte de l'última confirmació, però no s'ha preparat A Changes not staged for commit
Preparat staged La seva versió actual entrarà a la pròxima confirmació A Changes to be committed

Hi ha una distinció de fons que convé fixar: rastrejat enfront de no rastrejat. Un fitxer està rastrejat si apareix a l'última confirmació o a l'àrea de preparació; és a dir, si Git el coneix. Els tres estats "sense modificar", "modificat" i "preparat" són variants de rastrejat. "Sense seguiment" és l'única categoria de fora.

Aquesta distinció importa perquè moltes ordres actuen només sobre fitxers rastrejats. Per exemple, git commit -a prepara automàticament els fitxers modificats, però no els que estan sense seguiment; cal afegir-los a mà almenys una primera vegada.

Un detall clau: un fitxer pot estar en dos estats alhora

Fixa't en la transició Preparat --> Modificat del diagrama. És real i passa constantment:

  1. L'Ana modifica app.js i el prepara amb git add app.js. L'àrea de preparació desa aquesta versió.
  2. L'Ana continua treballant i torna a tocar app.js. Ara el disc té una versió més nova que l'àrea de preparació.

Resultat: app.js apareix a les dues seccions de git status, la de preparats i la de no preparats. No és un error ni una anomalia: hi ha dues versions diferents desades en dues zones diferents, i si l'Ana confirmés ara, hi entraria la preparada (la més antiga), no la del disc.

  1. git status: la brúixola

Si t'haguessis de quedar amb una sola ordre de Git, seria aquesta. No modifica res, és instantània i respon sempre les mateixes quatre preguntes: en quina branca ets, com estàs respecte del remot, què hi ha preparat i què hi ha pendent.

Llegim una sortida completa, amb tots els casos alhora:

git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   estils.css
	new file:   .gitignore

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   app.js
	deleted:    antic.js

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	notes.txt

Disseccionem-ho bloc a bloc:

Capçalera.

  • On branch main: la branca actual. És el primer que cal mirar; equivocar-se de branca és un clàssic.
  • Your branch is up to date with 'origin/main': comparació amb la branca de seguiment del remot. Només apareix si hi ha un remot configurat, com al clon d'en Bruno. També pot dir ahead by N commits o behind by N commits. Ho desenvoluparem al mòdul 4.

Changes to be committed — l'àrea de preparació. Tot el que hi aparegui entrarà al pròxim git commit. Cada línia porta un verb que indica el tipus de canvi: modified, new file, deleted, renamed.

Changes not staged for commit — canvis al directori de treball sobre fitxers que Git ja rastreja, però que no entraran al pròxim commit. Compte: aquí només hi apareixen fitxers rastrejats.

Untracked files — fitxers que Git veu per primera vegada. No entraran mai a cap confirmació fins que facis git add explícitament.

Els suggeriments entre parèntesis. Git t'indica, a cada secció, com avançar i com retrocedir. Val la pena llegir-los: són la millor documentació en línia que existeix.

Les sortides que veuràs més sovint

On branch main
nothing to commit, working tree clean

Tot confirmat, res pendent. Les tres zones coincideixen. És l'estat ideal per canviar de tasca.

On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	notes.txt

nothing added to commit but untracked files present (use "git add" to track)

No hi ha res preparat. Si fessis git commit ara, Git s'hi negaria perquè no hi hauria res a confirmar.

On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
	modified:   app.js

no changes added to commit (use "git add" and/or "git commit -a")

Has treballat, però no has preparat res. L'última línia és l'advertència: git commit a seques no faria res.

  1. git status --short: la forma abreujada i la seva taula de codis

La sortida llarga és excel·lent per aprendre, però cansa quan la consultes quaranta vegades al dia. La forma curta cap en una pantalla:

git status --short
git status -s          # equivalent
M  estils.css
A  .gitignore
 M app.js
 D antic.js
?? notes.txt

La clau és que hi ha dues columnes abans del nom del fitxer, i signifiquen coses diferents:

  • Columna 1 (esquerra): l'estat a l'ÀREA DE PREPARACIÓ.
  • Columna 2 (dreta): l'estat al DIRECTORI DE TREBALL.

Entendre això converteix una sortida críptica en informació precisa. Els codis possibles:

Codi Nom Significat
(espai) sense canvis Res a reportar en aquesta zona
M modified Modificat
A added Afegit (fitxer nou, ja preparat)
D deleted Esborrat
R renamed Reanomenat
C copied Copiat
U updated but unmerged Conflicte sense resoldre (el veuràs al mòdul 3)
? untracked Sense seguiment (apareix com a ??)
! ignored Ignorat (només amb --ignored)

I ara les combinacions que realment apareixen en el dia a dia:

Sortida Columna 1 Columna 2 Interpretació
M M Modificat i preparat. Hi entrarà tal qual
M M Modificat sense preparar. No hi entrarà
MM M M Preparat i tornat a modificar després. Hi entrarà la versió preparada
A A Fitxer nou, ja preparat
AM A M Afegit i modificat després d'afegir-lo
D D Esborrat, i l'esborrat està preparat
D D Esborrat del disc, però sense preparar l'esborrat
R R Reanomenat, preparat
?? Sense seguiment
UU U U Conflicte: tots dos costats han modificat el fitxer

Aplicat a l'exemple anterior:

  • M estils.css → modificat i preparat. Hi entrarà al commit.
  • A .gitignore → nou i preparat. Hi entrarà.
  • M app.js → modificat però sense preparar. No hi entrarà. Fixa't en l'espai inicial: és significatiu.
  • D antic.js → esborrat del disc, sense preparar. El commit continuaria incloent el fitxer.
  • ?? notes.txt → sense seguiment. No hi entrarà.

Truc de lectura. Posa el dit sobre la primera columna: el que queda tapat és "el que hi ha al disc". Descobreix-la: el que hi veus és "el que entrarà al commit".

Una variant molt útil hi afegeix la informació de branca:

git status -sb
## main...origin/main [ahead 2]
M  estils.css
 M app.js
?? notes.txt

La primera línia resumeix branca actual, branca de seguiment i divergència. Amb -sb tens en cinc línies tot el que la sortida llarga explica en vint-i-cinc.

  1. Fitxers que no vols versionar: .gitignore en dos minuts

Hi ha un problema pràctic amb Untracked files: moltes carpetes de projecte acumulen fitxers que mai no s'han de versionar. Dependències instal·lades, resultats de compilació, fitxers temporals de l'editor, credencials, fitxers del sistema operatiu… Si apareixen tots a cada git status, el senyal es perd entre el soroll i acabes ignorant la sortida de l'ordre, que és justament el que no vols.

La solució és un fitxer anomenat .gitignore a l'arrel del projecte, amb un patró per línia:

# Dependències
node_modules/

# Credencials
.env

# Registres i temporals
*.log
notes.txt

# Fitxers del sistema
.DS_Store
Thumbs.db

Els fitxers que coincideixin amb aquests patrons desapareixen de git status i no es poden afegir per accident amb git add .. El mateix .gitignore sí que es versiona: és part del projecte i ha de ser igual per a tot l'equip, cosa que resol de passada un conflicte històric entre els tres sistemes operatius de l'Ana, en Bruno i la Carla (.DS_Store a macOS, Thumbs.db a Windows).

Dos matisos que eviten la frustració més comuna:

  • .gitignore només afecta els fitxers sense seguiment. Si un fitxer ja està rastrejat, afegir-lo al .gitignore no el treu del projecte: cal treure'l de l'índex explícitament, una cosa que veurem a Preparant i Confirmant Canvis.
  • Escriu-lo aviat, idealment abans del primer git add, com vam veure a Creant un Repositori.

Amb això tens el necessari per treballar. Els patrons avançats, les negacions amb !, els .gitignore per subdirectori, el fitxer global i .git/info/exclude es tracten a fons a Ignorant Fitxers amb .gitignore.

  1. Una sessió de treball completa de l'Ana, narrada

Seguirem l'Ana durant una tarda sencera. És dimarts i vol afegir un comptador de tasques pendents a gestor-tasques. Punt de partida:

cd ~/projectes/gestor-tasques
git status
On branch main
nothing to commit, working tree clean

Tot net: les tres zones coincideixen amb l'última confirmació. És el punt de partida correcte per començar alguna cosa nova.

17:05 — Edita tres fitxers

Afegeix l'element del comptador a index.html:

  <h1>Gestor de Tasques</h1>
  <p id="comptador">0 tasques pendents</p>
  <form id="nova-tasca">

Li dona estil a estils.css:

#comptador {
  color: #6b7280;
  font-size: 0.9rem;
  margin: 0 0 1rem;
}

I afegeix la lògica a app.js:

function actualitzaComptador() {
  const pendents = tasques.filter(function (t) { return !t.feta; }).length;
  document.querySelector('#comptador').textContent = pendents + ' tasques pendents';
}

De passada, arrenca el projecte per provar-lo, cosa que genera un fitxer de registre, i obre un bloc de notes amb idees soltes.

17:40 — Primera consulta

git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   app.js
	modified:   estils.css
	modified:   index.html

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	depuracio.log
	notes.txt

no changes added to commit (use "git add" and/or "git commit -a")

Cinc entrades: tres fitxers del projecte modificats i dos fitxers nous que no vol versionar. L'última línia li recorda que, tal com està, git commit no faria res.

17:42 — Treu el soroll

Abans de preparar res, escriu el .gitignore:

cat > .gitignore <<'FI'
# Registres
*.log

# Notes personals
notes.txt
FI
git status -s
 M app.js
 M estils.css
 M index.html
?? .gitignore

depuracio.log i notes.txt han desaparegut. Ara la sortida només conté senyal. Fixa't en les tres línies que comencen per espai: columna 1 buida significa que res d'això no entraria encara en un commit.

17:45 — Prepara

git add index.html estils.css app.js .gitignore
git status -s
A  .gitignore
M  app.js
M  estils.css
M  index.html

La M i la A s'han desplaçat a la primera columna. Els quatre fitxers estan preparats. En la forma llarga:

git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   .gitignore
	modified:   app.js
	modified:   estils.css
	modified:   index.html

Ha desaparegut la secció de "no preparats": no queda res pendent al directori de treball.

17:52 — S'adona d'una errada

Provant la pàgina, l'Ana veu que el comptador diu "1 tasques pendents". Corregeix app.js perquè el singular funcioni:

function actualitzaComptador() {
  const pendents = tasques.filter(function (t) { return !t.feta; }).length;
  const text = pendents === 1 ? '1 tasca pendent' : pendents + ' tasques pendents';
  document.querySelector('#comptador').textContent = text;
}

I consulta de nou:

git status -s
A  .gitignore
MM app.js
M  estils.css
M  index.html

Aquí hi ha el cas interessant: MM app.js. El fitxer apareix amb M a les dues columnes. Significa exactament això:

  • Columna 1 (M): hi ha una versió d'app.js preparada — la de les 17:45, sense la correcció del singular.
  • Columna 2 (M): el fitxer del disc és diferent d'aquesta versió preparada — té la correcció.

En la forma llarga es veu encara més clar, perquè el mateix fitxer surt dues vegades:

git status
On branch main
Changes to be committed:
	new file:   .gitignore
	modified:   app.js
	modified:   estils.css
	modified:   index.html

Changes not staged for commit:
	modified:   app.js

Si l'Ana confirmés ara, hi entraria la versió amb l'errada. És el parany clàssic de Git i la raó per la qual convé mirar git status just abans de confirmar.

17:53 — Torna a preparar

git add app.js
git status -s
A  .gitignore
M  app.js
M  estils.css
M  index.html

La segona columna d'app.js torna a estar buida. Ara la versió preparada és la bona.

17:55 — Confirma

git commit -m "Afegeix el comptador de tasques pendents"
[main 2f6a3c8] Afegeix el comptador de tasques pendents
 4 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 .gitignore
git status
On branch main
nothing to commit, working tree clean

Tornem al punt de partida. Les tres zones tornen a coincidir, ara sobre una confirmació nova. I comprovem que els fitxers ignorats continuen allà, simplement invisibles per a Git:

ls
app.js  depuracio.log  estils.css  index.html  notes.txt  README.md
git status --ignored -s
!! depuracio.log
!! notes.txt

Són al disc, marcats com a ignorats. Git els veu i decideix, deliberadament, no molestar-te amb ells.

El recorregut en un diagrama

sequenceDiagram
    participant D as Directori<br/>de treball
    participant I as Àrea de<br/>preparació
    participant R as Repositori

    Note over D,R: 17:05 — L'Ana edita 3 fitxers
    Note over D: app.js, estils.css, index.html modificats
    Note over D,R: 17:42 — Escriu el .gitignore
    Note over D: depuracio.log i notes.txt desapareixen de status
    D->>I: 17:45 git add (4 fitxers)
    Note over D,R: 17:52 — Corregeix una errada a app.js
    Note over D,I: app.js apareix com a MM
    D->>I: 17:53 git add app.js
    I->>R: 17:55 git commit -m "Afegeix el comptador..."
    Note over D,R: working tree clean

  1. El cicle a la pràctica diària

Amb el flux interioritzat, el dia a dia es redueix a un grapat d'hàbits:

El bucle mínim, que executaràs milers de vegades:

git status          # on sóc?
# ... editar ...
git add <fitxers>   # què agrupo?
git status          # és exactament això el que entrarà?
git commit -m "..."  # registrar

Quatre hàbits que marquen la diferència:

  1. git status abans de començar. Saber si arrenques d'un arbre net o si ahir et vas deixar alguna cosa a mitges evita barrejar dues tasques en una confirmació.
  2. git status abans de confirmar. És l'únic moment en què pots detectar un MM o un fitxer oblidat. Costa un segon.
  3. Confirma aviat i sovint. Una confirmació no és un lliurament ni una publicació: és un punt de desament. Un historial de vint confirmacions petites és infinitament més útil que un de dues confirmacions gegants.
  4. Acaba el dia amb l'arbre net sempre que puguis. Si no és possible, almenys deixa anotat en què estaves.

Què fer quan el bucle es trenca. Aquestes són les situacions més freqüents i la seva sortida; totes es desenvolupen a la lliçó següent:

Situació Ordre
He preparat un fitxer que no volia git restore --staged <fitxer>
Vull descartar els meus canvis d'un fitxer git restore <fitxer>
M'he equivocat al missatge de l'últim commit git commit --amend
Vull veure què he canviat exactament git diff (lliçó 02-05)
Vull veure què s'ha fet fins ara git log (lliçó 02-06)

Errors Habituals i Consells

  • Confirmar sense mirar git status. El cas MM —un fitxer preparat i després tornat a modificar— fa que entri a l'historial una versió que no és la que tens al davant. Un cop d'ull a l'estat abans de confirmar ho evita.
  • Creure que git add "desa" el fitxer. git add no desa res de manera permanent: copia el contingut actual a l'àrea de preparació. Si continues editant, aquesta còpia es queda vella.
  • Oblidar que git commit -a no inclou fitxers sense seguiment. L'opció -a prepara automàticament els fitxers rastrejats modificats o esborrats. Un fitxer nou cal afegir-lo amb git add almenys una vegada.
  • Ignorar la secció Untracked files. És on s'amaga el fitxer nou que vas oblidar afegir i pel qual el projecte no compila a la màquina del teu company.
  • Interpretar malament les dues columnes de --short. M (espai i ema) i M (ema i espai) signifiquen coses oposades. Si dubtes, fes servir la forma llarga.
  • Treballar amb git status ple de soroll. Si tens quaranta fitxers sense seguiment que no versionaràs mai, escriu el .gitignore. Un status llegible és una eina; un d'il·legible és una nosa.
  • Afegir el .gitignore massa tard. Si el fitxer ja està rastrejat, ignorar-lo no té cap efecte. Cal treure'l de l'índex primer.
  • Consell: defineix un àlies curt per a l'estat, ja que el faràs servir constantment: git config --global alias.s "status -sb". Després n'hi ha prou amb git s. Els àlies es tracten a Git Log i Àlies.
  • Consell: si git status triga molt en un projecte gran, sol ser símptoma que hi ha massa fitxers sense seguiment (dependències, artefactes de compilació). Un bon .gitignore ho arregla.

Exercicis

Exercici 1: Llegir l'estat sense executar Git

Un repositori mostra aquesta sortida:

## main...origin/main [ahead 1]
A  config.json
MM app.js
 M estils.css
D  antic.css
 D index.html
?? esborrany.txt
R  README.md -> LLEGEIXME.md

Respon raonadament:

  1. Quins fitxers entraran al pròxim git commit (sense fer servir -a) i amb quin canvi?
  2. Què li passa a app.js? Si es confirma ara, quina versió queda registrada?
  3. index.html s'ha esborrat del disc. Desapareixerà del projecte en confirmar?
  4. Quantes confirmacions té aquesta branca per davant del remot?
  5. Escriu la seqüència d'ordres que deixaria l'estat llest perquè tot l'esborrat, modificat i reanomenat entri al commit, llevat d'esborrany.txt, que no s'ha de versionar mai.

Exercici 2: Reproduir el cas MM

Crea un repositori de prova i provoca deliberadament la situació en què es confirma una versió antiga d'un fitxer:

  1. Crea un repositori amb un fitxer app.js que contingui la línia const versio = 1; i confirma'l.
  2. Canvia la línia a const versio = 2; i prepara el canvi.
  3. Sense confirmar, canvia la línia a const versio = 3;.
  4. Comprova l'estat en forma curta i llarga.
  5. Confirma sense tornar a preparar.
  6. Esbrina amb ordres quina versió ha quedat registrada a l'historial i quina continua al teu disc.
  7. Arregla la situació perquè l'historial reflecteixi la versió 3.

Exercici 3: Netejar el soroll d'un projecte heretat

Et passen un projecte en què git status mostra això:

On branch main
Untracked files:
	.env
	.vscode/settings.json
	build/index.js
	build/estils.css
	dist/paquet.zip
	informe.log
	node_modules/  (milers de fitxers)
	src/nouModul.js
	temp~

Només src/nouModul.js s'ha de versionar. Escriu:

  1. El .gitignore que deixa git status mostrant únicament aquest fitxer.
  2. Les ordres per verificar que funciona, inclosa una comprovació explícita que .env s'està ignorant i per quina regla.
  3. La seqüència per confirmar el .gitignore i el mòdul nou en dues confirmacions separades, i una justificació de per què separar-les.

Solucions

Solució a l'Exercici 1

1. Què entrarà al commit. Tot el que tingui alguna cosa diferent d'un espai a la primera columna:

Fitxer Codi Hi entra com a
config.json A Fitxer nou
app.js MM Modificat (la versió preparada)
antic.css D Esborrat
README.md -> LLEGEIXME.md R Reanomenat

No hi entren estils.css ( M), index.html ( D) ni esborrany.txt (??), perquè la seva primera columna és buida o són fitxers desconeguts per a Git.

2. app.js és el cas MM: hi ha una versió preparada i, a més, el fitxer del disc és diferent d'ella. En confirmar quedarà registrada la versió preparada, no la que hi ha al disc. La diferència entre totes dues es quedarà com a canvi pendent després del commit.

3. index.html no desapareixerà. El codi D indica que l'esborrat és al disc però no està preparat. La confirmació continuarà contenint el fitxer, així que qui cloni el repositori el rebrà. És un error habitual: esborrar amb l'explorador de fitxers i oblidar registrar l'esborrat.

4. Una confirmació per davant, segons [ahead 1]: hi ha un commit local que el remot encara no té.

5. La seqüència:

# 1. Excloure l'esborrany perquè no s'hi coli mai
echo "esborrany.txt" >> .gitignore

# 2. Preparar tot el pendent dels fitxers rastrejats,
#    inclosos els esborrats
git add -u

# 3. Preparar el .gitignore, que és un fitxer nou
git add .gitignore

# 4. Verificar abans de confirmar
git status -s
A  .gitignore
A  config.json
M  app.js
M  estils.css
D  antic.css
D  index.html
R  README.md -> LLEGEIXME.md

La segona columna és buida a totes les línies i esborrany.txt ha desaparegut: exactament el que es demanava. L'opció -u de git add és la clau —prepara modificacions i esborrats de fitxers ja rastrejats, sense tocar els nous— i l'estudiarem en detall a la lliçó següent.

Solució a l'Exercici 2

Passos 1 a 3:

mkdir -p ~/practica/estats && cd ~/practica/estats
git init
echo "const versio = 1;" > app.js
git add app.js
git commit -m "Versió inicial"

echo "const versio = 2;" > app.js
git add app.js

echo "const versio = 3;" > app.js

Pas 4 — l'estat:

git status -s
# → MM app.js

git status
On branch main
Changes to be committed:
	modified:   app.js

Changes not staged for commit:
	modified:   app.js

El mateix fitxer apareix dues vegades. La forma llarga ho fa evident; la curta ho condensa en MM.

Pas 5 — confirmar:

git commit -m "Actualitza la versió"
[main 4b8e2f1] Actualitza la versió
 1 file changed, 1 insertion(+), 1 deletion(-)

Pas 6 — què ha quedat on:

# El que hi ha a l'historial
git show HEAD:app.js
# → const versio = 2;

# El que hi ha al teu disc
cat app.js
# → const versio = 3;

# I continua havent-hi feina pendent
git status -s
# →  M app.js

Confirmat: hi ha entrat la versió 2, la que estava preparada. La 3 continua al directori de treball, encara sense registrar. Aquest és l'efecte exacte que produeix ignorar un MM.

Pas 7 — arreglar-ho:

git add app.js
git commit -m "Corregeix la versió a 3"
git show HEAD:app.js
# → const versio = 3;

És la solució més segura: una confirmació nova a sobre. (Existeix una altra alternativa, git commit --amend, que corregeix la confirmació anterior en lloc d'afegir-ne una de nova; s'estudia a la lliçó següent i convé fer-la servir només sobre confirmacions que encara no s'han compartit, perquè reescriu l'historial.)

Solució a l'Exercici 3

1. El .gitignore:

# Dependències
node_modules/

# Artefactes de compilació
build/
dist/

# Configuració local de l'editor
.vscode/

# Credencials
.env

# Registres i temporals
*.log
*~

2. Verificació:

git status -s
?? .gitignore
?? src/nouModul.js

Exactament dues entrades: el mateix .gitignore i el fitxer que sí que volem versionar.

Per comprovar per què s'ignora un fitxer concret existeix una ordre específica:

git check-ignore -v .env
.gitignore:11:.env	.env

La sortida indica el fitxer de regles, el número de línia, el patró que coincideix i el fitxer avaluat. És l'eina correcta per depurar un .gitignore que "no funciona": si l'ordre no retorna res, és que no s'hi aplica cap regla.

I una comprovació addicional que dona tranquil·litat:

git status --ignored -s | head -5
!! .env
!! .vscode/
!! build/
!! dist/
!! informe.log

3. Dues confirmacions separades:

git add .gitignore
git commit -m "Afegeix el .gitignore amb dependències, artefactes i credencials"

git add src/nouModul.js
git commit -m "Afegeix el mòdul de generació d'informes"

Per què separar-les. Són dos canvis sense cap relació: un configura què versiona el projecte i l'altre afegeix funcionalitat. Separar-los té avantatges concrets:

  • Cada confirmació es pot descriure amb una sola frase honesta.
  • Si demà cal revisar per què s'ignora dist/, es troba una confirmació que parla només d'això.
  • Si el mòdul nou resulta ser un error i cal desfer-lo, es desfà sense arrossegar el .gitignore.

És la idea de commit atòmic, que desenvolupem justament a la lliçó següent.

Conclusió

Ja tens el cicle complet. Recapitulant:

  • El flux bàsic són tres passos —editar, preparar, confirmar— i dues ordres, git add i git commit. El pas intermedi existeix per separar la feina (què he canviat) del criteri (què forma una unitat amb sentit).
  • Les tres zones es mouen amb ordres concretes: git add porta del directori de treball a l'àrea de preparació, git commit de l'àrea al repositori, i git restore desfà en totes dues direccions.
  • Un fitxer travessa quatre estats: sense seguiment, sense modificar, modificat i preparat. Només els tres últims corresponen a fitxers rastrejats, i moltes ordres actuen únicament sobre aquests.
  • Un mateix fitxer pot estar en dos estats alhora (el cas MM), i si no ho detectes confirmaràs una versió que no és la que tens al davant.
  • git status és la brúixola. En la seva forma llarga ensenya; en la seva forma curta (-s, -sb) informa d'un cop d'ull, amb dues columnes que separen l'àrea de preparació del directori de treball.
  • .gitignore manté el senyal net excloent el que mai no s'ha de versionar, però només actua sobre fitxers sense seguiment.

Amb això ja pots treballar. El que falta és precisió: fins ara hem preparat fitxers sencers amb git add <fitxer>, i això no sempre és el que vols. I si en un mateix fitxer tens dos canvis que pertanyen a confirmacions diferents? Com treus alguna cosa de l'àrea de preparació? Com s'esborra o es reanomena un fitxer dins de Git? I si t'equivoques al missatge del commit que acabes de fer?

De tot això tracta la lliçó següent, Preparant i Confirmant Canvis: git add a fons amb les seves opcions -A, -u i . —una font clàssica de confusió— i el mode interactiu per fragments, com desfer preparacions amb git restore, git mv i git rm, i totes les variants de git commit, inclosa --amend per corregir l'última confirmació.

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