Git és un sistema de control de versions.
Introducció
Avui en dia tothom espera que facis servir un sistema de gestió de control de versions, que acostuma a ser git.
Per això les IDE ja no s’encarreguen de recuperar fitxers esborrats, o versions anteriors d’un fitxer perquè donen per suposat que estas fent servir git.
Però tu fas servir git? Més aviat no.
Instal.la git
amb Windows - Scoop:
scoop install git
Primers passos
Configura git:
> git config --global init.defaultBranch main
Crea un directori test
per començar a treballar, i entra en ell:
mkdir test
cd test
Crea un fitxer hola.txt
, escriu alguna cosa en ell i borra el fitxer:
echo "Hola" > hola.txt
ls
rm hola.txt
ls
Et pot semblar un exercici una mica ximple, però esborrar el que no toca acostuma a passar i no és gens divertit.
Aquest cop versionem el directori amb git:
git init -b main
echo "Hola" > hola.txt
ls
rm hola.txt
ls
Pots verificar que hem tornat a perdre el fitxer perquè Git només guarda aquells fitxers que li han dit que guardi!
Tornem a començar, però aquest cop preguntem a git
:
echo "Hola" > hola.txt
git status
Pots veure que git
sap que el fitxer hola.txt
està en la carpeta, i t’avisa que no l’està controlant.
Untracked files:
(use "git add <file>..." to include in what will be committed)
hola.txt
Si vols que git
controli el fitxer, has de dir a git que ho faci amb la comanda git add
:
git add hola.txt
git status
Perfecte!
Changes to be committed:
new file: hola.txt
Ara esborrem el fitxer i llestos
$ rm hola.txt
$ ls
Doncs el fitxer s’ha esborrat 😐
I que ha fet git
al respecte?
git status
Com que git
ara controla tot el que passa amb el fitxer hola.txt
saps que l’has esborrat.
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hola.txt
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: hola.txt
git
et dona dues opcions:
- Oblidar del fitxer →
git rm hola.txt
- Restaurar el fitxer →
git restore hola.txt
En aquest cas el que volem és recuperar el fitxer:
$ git restore hola.txt
Si has esborrat el fitxer, ¿com és que git el pot recuperar?
Doncs perquè quan vas fer git add hola.txt
es va guardar una còpia en la carpeta .git
Si fas un ls -forece
…
$ ls -force
Pots veure la carpeta oculta que es va crear abans quan vas executar l’ordre git init
d--h-- 20/9/2025 11:21 .git
-a---- 20/9/2025 11:21 14 hola.txt
Si fas un git status
…
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hola.txt
Modifica el fitxer hola.txt
i mira que passa quan fas git status
:
echo "Adeu" > hola.txt
git status
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hola.txt
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: hola.txt
Git té una còpia del fitxer hola.txt
que fas afegir quan vas fer git add
(té aquella versió).
També sap que no es correspon al fitxer actual (algú l’ha modificat).
Si vols recuperar la versió guardada en la carpeta .git
has de fer un git restore
tal com t’explica el mateix git
:
git restore hola.txt
Verifica que el fitxer hola.txt
s’ha restaurat amb cat hola.txt
:
git restore hola.txt
cat hola.txt
Commit
El que fa molt interessant a un sistema de control de versions és que pots anar guardant els canvis un darrere l’altre i tornar enrere quan vulguis.
Si vols guardar els canvis de forma permanent has de fer un commit:
$ git commit -m "He afegit el fitxer hola.txt"
Author identity unknown
*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
git
no et deixa fer un commit!
Per fer un commit has de configurar el teu nom i correu electrònic perquè quedi constància de qui ha fet que.
I a qui li interessa això si jo ja sé qui soc?
Doncs perquè git crea el que es coneix com un repositori que es pot compartir de manera col·laborativa amb altra gent i ha de quedar constància de qui ha fet que.
Configura el teu nom i correu electrònic:
git config --global user.email "ddemingo@xtec.cat""
git config --global user.name "David de Mingo"
I ja pots fer un commit:
git commit -m "He afegit el fitxer hola.txt"
[main (root-commit) 7161397] He afegit el fitxer hola.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 hola.txt
Si demanes a git
que et mostri el log
git log
Pots veure que David de Mingo ha afegit el fitxer hola.txt
al repositori.
commit 71613970c7c8829e5ff71f3d8e8c01fd6984b4d5 (HEAD -> main)
Author: David de Mingo <david@optersoft.com>
Date: Sat Sep 20 11:34:04 2025 +0200
He afegit el fitxer hola.txt
Suposo que encara no saps exactament de que va tot això i ho trobes poc interessant
Doncs fem un commit:
echo "Dilluns" > hola.txt
git add hola.txt
git commit -m "Ara és dilluns"
I ara un altre commit:
echo "Dimarts" > hola.txt
git add hola.txt
git commit -m "Ara és dimarts"
Si fas git log
pots veure totes les modificacions que s’han guardat:
commit 1d30a16b5d624a172c590b34807729cb4d49d228 (HEAD -> main)
Author: David de Mingo <david@optersoft.com>
Date: Sat Sep 20 11:43:07 2025 +0200
Ara és dimarts
commit 5a9aa4d9f636bf6813f97ea0b011c738decc6d63
Author: David de Mingo <david@optersoft.com>
Date: Sat Sep 20 11:42:51 2025 +0200
Ara és dilluns
commit 71613970c7c8829e5ff71f3d8e8c01fd6984b4d5
Author: David de Mingo <david@optersoft.com>
Date: Sat Sep 20 11:34:04 2025 +0200
He afegit el fitxer hola.txt
Checkout
Cada modificació (commit) tè un identificador únic tal com pots veure a la sortida de la comanda git log
.
Aquest identificador és un hash criptogràfic (mira Seguretat - Criptografia)
Que haig de fer per poder veure les diferents versions del fitxer hola?
Demanar a git que restauri la versió que tu vols amb la comanda checkout
:
git checkout 7161
A continuació apareix un missatge molt llarg i interessant:
Note: switching to '7161'.
You are in 'detached HEAD' state.
You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 7161397 He afegit el fitxer hola.txt
HEAD
és un apuntador simbòlic a “on ets” dins de la història.
git
guarda aquesta informació en el fitxer .git/HEAD
:
cat .\.git\HEAD
Que com pots veure és només un identificador de commit:
71613970c7c8829e5ff71f3d8e8c01fd6984b4d5
I el contingut del fitxer …
cat hola.txt
És el que tu esperes:
Hola
Fes un checkout
al commit 5a9a
:
git checkout 5a9a
Previous HEAD position was 7161397 He afegit el fitxer hola.txt
HEAD is now at 5a9aa4d Ara és dilluns
Pots veure que no cal que escriguis tot l’identificador, amb els primers dígits és suficient.
I per tornar a la versió més actual pots fer servir l’identificador del commit o el de la branca (en parlem després):
git checkout main
Previous HEAD position was 5a9aa4d Ara és dilluns
Switched to branch 'main'
Tag
Això dels identificadors està molt bé pels ordinadors, però les persones fem servir noms perquè és més fàcil per nosaltres. Recordes de memòria d’algun número de telèfon?
Git permet etiquetar commits amb l’etiqueta que nosaltres vulguem.
Per exemple, pots etiquetar el commit actual amb l’etiqueta “dimarts”
git tag dimarts
I pots etiquetar el commit “Ara és dilluns” amb l’etiqueta “dilluns” (aquest cop haig d’indicar la id del commit):
git tag dilluns 5a9a
Pots veure que tenim dues etiquetes:
git tag
dilluns
dimarts
Pots veure la informació del commit etiquetat:
git show dilluns
commit 5a9aa4d9f636bf6813f97ea0b011c738decc6d63 (HEAD, tag: dilluns)
Author: David de Mingo <david@optersoft.com>
Date: Sat Sep 20 11:42:51 2025 +0200
Ara és dilluns
diff --git a/hola.txt b/hola.txt
index b35a5e3..8c77065 100644
Binary files a/hola.txt and b/hola.txt differ
Pots canviar de versió fent checkout
del tag:
git checkout dilluns
Note: switching to 'dilluns'.
HEAD is now at 5a9aa4d Ara és dilluns
Torna al “main”.
git checkout main
També pots esborrar etiquetes:
git tag -d dilluns
git tag
dimarts
Tens més informació sobre les etiquetes en el document Basics - Tagging
Ignore
Potser et sorprendrà, però git només el fan servir els programadors
I els programadors escrivim codi que s’ha de compilar. I que vol dir compilar? Doncs que es creen nous fitxers i executables, que necessitem llibreries, etc. i que naturalment no s’han versionar!
I com pot saber git que s’ha de versionar i que no s’ha de versionar? Doncs no tè ni idea, és la teva feina!
Per això has de dir explícitament quins fitxers ha de controlar amb git add
. Però també has de saber que un bon programador sempre troba la manera de fer menys per aconseguir més.
Crea dos fitxers i fes un git add –-all
:
echo "Lluna blava" > lluna.txt
echo "Mar vermell" > mar.txt
git add --all
Però si ho afegim tot, potser també afegim el que no s’ha d’afegir.
Podem crear un fitxer .gitignore
on indicarem tots els fitxers i carpetes que git
sempre ha d’ignorar.
Crea una carpeta tmp
on guardar fitxers temporals:
mkdir tmp
I a continuació crea un fitxer .gitignore
on indicarem que no vols que git
controli la carpeta tmp
:
echo "tmp/" > .gitignore
Afegeix tots els fitxers a git
i fes un commit:
git add .
git commit -m "Afegit lluna.txt i mar.txt, ignorem el directori tmp"
Fixa’t que git
només controla fitxers, en cap cas directoris:
[main 5a7a09f] Afegit lluna.txt i mar.txt, ignorem el directori tmp
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 .gitignore
create mode 100644 lluna.txt
create mode 100644 mar.txt
NO FUNCIONA
echo "tmp" > .gitignore
echo "Terra groga" > tmp/terra.txt
echo "Llac blanc" > tmp/llac.txt
Si executes git status
pots veure que el fitxer llac.txt
no s’ha afegit a la llista de fitxers que git
ha de controlar, perquè el fitxer .gitignore
diu que ha d’ignorar tots els fitxers que acabin amb .txt
.
Branques
I ara comencem una sessió de jardineria!
Quan fas un projecte de programació, quan fas un examen de programació, mai et surt res a la primera. Vas fent, t’equivoques, tornes enrere (has de desfer coses), intentes coses noves, etc., i tot és un galimaties.
La programació és així, i la majoria de les tasques de la teva vida diària són així.
Per poder treballar de manera segura sempre has de poder avançar des d’una posició segura a una altra posició segura.
I més important, poder tornar a una posició segura en què tot funciona.
Per això git
permet crear branques de treball.
Branch
Crear una branca és molt fàcil:
git branch test
Anem a veure quantes branques tenim:
git branch
Tens dues branques, i estas en la branca main
(està marcada amb *
).
* main
test
Ara mateix les dues branques (main
és una branca com qualsevol altre) són iguals perquè totes dues estan apuntant al mateix commit.
git log -n 1
L’única diferència és que HEAD
apunta a l’etiqueta main
:
commit 5a7a09fa12cf72718870551fc0c22663e4774063 (HEAD -> main, test)
Author: David de Mingo <david@optersoft.com>
Date: Sun Sep 21 12:09:57 2025 +0200
Afegit lluna.txt i mar.txt, ignorem el directori tmp
El que anem a fer ara és canviar a la branca test
:
git checkout test
git log -n 1
commit 5a7a09fa12cf72718870551fc0c22663e4774063 (HEAD -> test, main)
Author: David de Mingo <david@optersoft.com>
Date: Sun Sep 21 12:09:57 2025 +0200
Afegit lluna.txt i mar.txt, ignorem el directori tmp
Ara ja podem crear un fitxer i fer un commit:
echo "Una nit d'estiu" > nit.txt
git add nit.txt
git commit -m "Afegit nit.txt"
Si tornem a la branca main
pots veure que tot els commit nous de la branca test no apareixen.
git checkout main
git log -n 1
commit 5a7a09fa12cf72718870551fc0c22663e4774063 (HEAD -> main)
Author: David de Mingo <david@optersoft.com>
Date: Sun Sep 21 12:09:57 2025 +0200
Afegit lluna.txt i mar.txt, ignorem el directori tmp
Per tant, el fitxer nit.txt
no existeix:
cat nit.txt
cat : Cannot find path 'C:\Users\david\Workspace\tmp\git\nit.txt' because it does not exist
Si volem esborrar la branca test
, git ens avisa que tots els commits nous de la branca test
es perdran.
git branch -d test
error: the branch 'test' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D test'
hint: Disable this message with "git config set advice.forceDeleteBranch false"
Merge
Si el que he fet en la branca test
està bé i funcional puc fusionar els canvis a la branca principal:
git merge test
Updating 5a7a09f..3409713
Fast-forward
nit.txt | Bin 0 -> 36 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 nit.txt
Ara ja tens el fitxer nit.txt
a la branca principal:
cat nit.txt
I pots esborrar la branca test
:
git branch -d test
Deleted branch test (was 3409713)
De totes maneres molts alumnes no veuen la necessitat de crear una branca per una cosa tant simple.
Doncs anem a fer una activitat ben divertida (almenys pel profe 🙄).
Activitat
Els fitxers de la teva solució han de ser diferents 🤨
✅ Crea una carpeta nova (fora de la que has utilitzat fins ara), on estarà el teu petit projecte i versiona la carpeta
mkdir poesia
cd poesia
git init -b main
✅ Crea un fitxer de text amb algun contingut i fes un commit del nou fitxer.
echo "Topant de cap en una i altra soca," > la-vaca-cega.txt
git add la-vaca-cega.txt
git commit -m "Afegit la vaca cega"
✅ Crea una nova branca dev
, canvia de branca, modifica el fitxer que has creat i fes un commit.
git branch dev
git checkout dev
echo "Topant de cap en una i altra soca," >> la-vaca-cega.txt
git commit -a -m "Seguim amb l'estrofa"
✅ Torna a la branca main
i fes un merge de la branca dev
.
git checkout main
git merge dev
git branch -d dev
✅ Fes un checkout del primer commit i verifica que és la primera versió del fitxer de text.
git checkout 79d2320
cat la-vaca-cega.txt
✅ Torna a l’últim commit.
git checkout main
✅ Acaba d’escriure el contingut del fitxer de text i fes un altre commit:
echo "se'n ve la vaca tota sola. És cega." >> .\la-vaca-cega.txt
git commit -a -m "Estrofa completa"
✅ Etiqueta el commit actual.
git tag vaca-cega
✅ Fes un git log
per veure tot l’historial
commit ed98c39581ba582f183a556487c6013071f5cfc6 (HEAD -> main, tag: vaca-cega)
Author: David de Mingo <david@optersoft.com>
Date: Sun Sep 21 13:24:28 2025 +0200
Estrofa completa
commit 27959606a1d0fdf0a8a208dbbd42ac9ca1075f0a
Author: David de Mingo <david@optersoft.com>
Date: Sun Sep 21 13:13:49 2025 +0200
Seguim amb l'estrofa
commit 79d23200d10572f857a50837accb8bffc194aee3
Author: David de Mingo <david@optersoft.com>
Date: Sun Sep 21 13:11:32 2025 +0200
Afegit la vaca cega