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 gitPrimers passos
Configura git:
> git config --global init.defaultBranch mainCrea un directori test per començar a treballar, i entra en ell:
mkdir testcd testCrea un fitxer hola.txt, escriu alguna cosa en ell i borra el fitxer:
echo "Hola" > hola.txtlsrm hola.txtlsEt 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 mainecho "Hola" > hola.txtlsrm hola.txtlsPots 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.txtgit statusPots 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.txtSi vols que git controli el fitxer, has de dir a git que ho faci amb la comanda git add:
git add hola.txtgit statusPerfecte!
Changes to be committed: new file: hola.txtAra esborrem el fitxer i llestos
$ rm hola.txt$ lsDoncs el fitxer s’ha esborrat 😐
I que ha fet git al respecte?
git statusCom 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.txtgit 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.txtSi 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 -forcePots 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.txtSi fas un git status …
Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: hola.txtModifica el fitxer hola.txt i mira que passa quan fas git status:
echo "Adeu" > hola.txtgit statusChanges 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.txtGit 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.txtVerifica que el fitxer hola.txt s’ha restaurat amb cat hola.txt:
git restore hola.txtcat hola.txtCommit
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"Per verificar que l’alumne ha fet el que havia de fer executa aquesta comanda:
$ git config --listinit.defaultbranch=mainuser.email=ddemingo@xtec.catuser.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.txt1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 hola.txtSi demanes a git que et mostri el log
git logPots 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.txtSuposo que encara no saps exactament de que va tot això i ho trobes poc interessant
Doncs fem un commit:
echo "Dilluns" > hola.txtgit add hola.txtgit commit -m "Ara és dilluns"I ara un altre commit:
echo "Dimarts" > hola.txtgit add hola.txtgit 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 5a9aa4d9f636bf6813f97ea0b011c738decc6d63Author: David de Mingo <david@optersoft.com>Date: Sat Sep 20 11:42:51 2025 +0200
Ara és dilluns
commit 71613970c7c8829e5ff71f3d8e8c01fd6984b4d5Author: David de Mingo <david@optersoft.com>Date: Sat Sep 20 11:34:04 2025 +0200
He afegit el fitxer hola.txtCheckout
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 7161A continuació apareix un missatge molt llarg i interessant:
Note: switching to '7161'.
You are in 'detached HEAD' state.You can look around, make experimentalchanges and commit them, and you can discard any commits you make in thisstate without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you maydo 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.txtHEAD és un apuntador simbòlic a “on ets” dins de la història.
git guarda aquesta informació en el fitxer .git/HEAD:
cat .\.git\HEADQue com pots veure és només un identificador de commit:
71613970c7c8829e5ff71f3d8e8c01fd6984b4d5I el contingut del fitxer …
cat hola.txtÉs el que tu esperes:
HolaFes un checkout al commit 5a9a:
git checkout 5a9aPrevious HEAD position was 7161397 He afegit el fitxer hola.txtHEAD is now at 5a9aa4d Ara és dillunsPots 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 mainPrevious HEAD position was 5a9aa4d Ara és dillunsSwitched 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 dimartsI pots etiquetar el commit “Ara és dilluns” amb l’etiqueta “dilluns” (aquest cop haig d’indicar la id del commit):
git tag dilluns 5a9aPots veure que tenim dues etiquetes:
git tagdillunsdimartsPots veure la informació del commit etiquetat:
git show dillunscommit 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.txtindex b35a5e3..8c77065 100644Binary files a/hola.txt and b/hola.txt differPots canviar de versió fent checkout del tag:
git checkout dillunsNote: switching to 'dilluns'.HEAD is now at 5a9aa4d Ara és dillunsTorna al “main”.
git checkout mainTambé pots esborrar etiquetes:
git tag -d dillunsgit tagdimartsTens 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.txtecho "Mar vermell" > mar.txtgit add --allPerò si ho afegim tot, potser també afegim el que no s’ha d’afegir.
Pots crear un fitxer .gitignore on indicar tots els fitxers i carpetes que git sempre ha d’ignorar.
Crea una carpeta tmp on guardar fitxers temporals:
mkdir tmpI a continuació crea un fitxer .gitignore on indiques a git que no vols que controli la carpeta tmp:
echo "tmp/" > .gitignoreAfegeix 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 tmp3 files changed, 0 insertions(+), 0 deletions(-)create mode 100644 .gitignorecreate mode 100644 lluna.txtcreate mode 100644 mar.txtNO FUNCIONA
echo "Terra groga" > tmp/terra.txtecho "Llac blanc" > tmp/llac.txtSi 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 estigui a la carpeta tmp:
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 testAnem a veure quantes branques tenim:
git branchTens dues branques, i estas en la branca main (està marcada amb *).
* main testAra 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 1L’ú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 tmpEl que anem a fer ara és canviar a la branca test:
git checkout testgit log -n 1commit 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 tmpAra ja podem crear un fitxer i fer un commit:
echo "Una nit d'estiu" > nit.txtgit add nit.txtgit 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 maingit log -n 1commit 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 tmpPer tant, el fitxer nit.txt no existeix:
cat nit.txtcat : Cannot find path 'C:\Users\david\Workspace\tmp\git\nit.txt' because it does not existSi volem esborrar la branca test, git ens avisa que tots els commits nous de la branca test es perdran.
git branch -d testerror: the branch 'test' is not fully mergedhint: 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 testUpdating 5a7a09f..3409713Fast-forward nit.txt | Bin 0 -> 36 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 nit.txtAra ja tens el fitxer nit.txt a la branca principal:
cat nit.txtI pots esborrar la branca test:
git branch -d testDeleted 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 poesiacd poesiagit 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.txtgit add la-vaca-cega.txtgit 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 devgit checkout devecho "Topant de cap en una i altra soca," >> la-vaca-cega.txtgit commit -a -m "Seguim amb l'estrofa"✅ Torna a la branca main i fes un merge de la branca dev.
git checkout maingit merge devgit branch -d dev✅ Fes un checkout del primer commit i verifica que és la primera versió del fitxer de text.
git checkout 79d2320cat 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.txtgit 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 27959606a1d0fdf0a8a208dbbd42ac9ca1075f0aAuthor: David de Mingo <david@optersoft.com>Date: Sun Sep 21 13:13:49 2025 +0200
Seguim amb l'estrofa
commit 79d23200d10572f857a50837accb8bffc194aee3Author: David de Mingo <david@optersoft.com>Date: Sun Sep 21 13:11:32 2025 +0200
Afegit la vaca cega