Git és un sistema de control de versions lliure i distribuït dissenyat per gestionar
projectes xicotets i grans amb rapidesa i eficiència. El seu objectiu principal és controlar i gestionar
els canvis realitzats en una gran quantitat de fitxers d'una manera fàcil i eficient.
Git va ser dissenyat en 2005 per Linus Torvalds, creador del nucli (kernel) del sistema operatiu Linux.
Des d'aleshores, s'ha convertit en una ferramenta imprescindible per a gestionar el codi font
dels projectes col·laboratius.
Git està basat en repositoris. Un repositori s'inicialitza en un directori concret i conté tota
la informació dels canvis realitzats en l'arbre de directoris i fitxers a partir d'aquest directori.
Els principals objectius i característiques de Git són:
Control de versions: Git fa un seguiment de les modificacions dels fitxers al llarg del temps,
la qual cosa permet a l'equip de desenvolupament vore i recuperar versions anteriors del codi.
Aquesta característica és essencial per a treballar en equip i per a solucionar errors.
Distribuït: cada còpia d'un repositori Git conté tot l'historial de canvis i pot funcionar
de manera independent. Això facilita el treball fora de línia i la col·laboració en equips distribuïts.
Branques i fusions: Git facilita la creació de branques (branching) per a desenvolupar
funcionalitats o solucionar problemes sense afectar la branca principal.
Després, les branques es poden fusionar (merge) de nou en la branca principal quan estiguen a punt.
Gestió de conflictes: Git ofereix ferramentes per a gestionar els conflictes que apareixen quan
dues o més persones han modificat la mateixa part del codi. Aquests conflictes es resolen manualment.
Col·laboració: Git permet que moltes persones treballen en el mateix projecte de manera eficient.
Plataformes com GitHub, GitLab, Bitbucket
i Codeberg s'utilitzen habitualment per a allotjar repositoris Git en línia
i col·laborar en projectes.
Codi obert i gratuït: qualsevol persona pot utilitzar Git sense cost i contribuir al seu desenvolupament.
En aquests apunts s'utilitza Git des de la terminal. Els motius d'aquesta elecció s'expliquen
en l'apartat Per què la terminal?.
Tingues en compte els aspectes següents a l'hora d'inicialitzar un repositori amb git init:
No cal inicialitzar el repositori cada vegada que vulgues treballar-hi.
L'estat del repositori s'emmagatzema de manera persistent en el directori ocult .git.
Si inicialitzes un repositori en un directori que ja conté un repositori,
es crea un nou repositori i el contingut del directori .git se sobreescriu,
de manera que s'elimina tota la informació anterior.
Encara que és possible1, no és recomanable inicialitzar un repositori en un directori
que ja es troba dins d'un altre repositori.
Si no s'ha configurat d'una altra manera, Git anomena master la branca principal.
La comunitat de desenvolupament ha recomanat canviar aquest nom a main
per a evitar les connotacions històriques negatives associades al terme master2.
Per utilitzar main com a nom per defecte de la branca principal en els nous repositoris,
es pot executar l'ordre següent:
gitconfig--globalinit.defaultBranchmain
Exemple: Inicialització d'un repositori
Es crea el directori git_introduccio i s'hi inicialitza un repositori.
jpuigcerver@fp:~$mkdirgit_introduccio
jpuigcerver@fp:~$cdgit_introduccio
jpuigcerver@fp:~/git_introduccio$ls-a# (1)!. ..jpuigcerver@fp:~/git_introduccio$gitinit
hint: Using 'master' as the name for the initial branch. This default branch namehint: is subject to change. To configure the initial branch name to use in allhint: of your new repositories, which will suppress this warning, call:hint:hint: git config --global init.defaultBranch <name>hint:hint: Names commonly chosen instead of 'master' are 'main', 'trunk' andhint: 'development'. The just-created branch can be renamed via this command:hint:hint: git branch -m <name>Initialized empty Git repository in /home/jpuigcerver/git_introduccio/.git/jpuigcerver@fp:~/git_introduccio(master)$gitbranch-mmain# (2)!jpuigcerver@fp:~/git_introduccio(main)$ls-a# (3)!. .. .git/jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainNo commits yetNothing to commit (create/copy files and use "git add" to track)
L'opció -a mostra tots els fitxers, inclosos els ocults, que comencen amb un punt.
Es canvia el nom de la branca principal de master a main.
S'ha creat el directori ocult .git, que conté tota la informació del repositori.
L'ordre git status mostra l'estat actual del repositori.
S'observa que la branca actual és main i que encara no s'ha fet cap canvi.
Git emmagatzema tota la informació del repositori en el directori ocult .git.
Per tant, per a eliminar un repositori, n'hi ha prou amb eliminar aquest directori:
rm-rf.git
-r: elimina el directori de manera recursiva.
-f: força l'eliminació, sense demanar confirmació, dels elements protegits contra escriptura.
Sigues molt prudent amb l'ordre rm -rf, ja que elimina tots els fitxers, inclosos els protegits contra escriptura.
Exemple: Eliminar un repositori
S'elimina el repositori creat en l'exemple anterior.
jpuigcerver@fp:~/git_introduccio(main)$ls-a
. .. .gitjpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainNo commits yetNothing to commit (create/copy files and use "git add" to track)jpuigcerver@fp:~/git_introduccio(main)$rm-rf.git
jpuigcerver@fp:~/git_introduccio$gitstatus
fatal: not a git repository (or any of the parent directories): .git
S'observa que, després d'eliminar el directori .git, Git ja no reconeix el directori com a repositori.
Aquesta introducció se centra en el funcionament local dels repositoris de Git,
sense connectar encara cap repositori remot. Abans que res, cal conéixer l'estructura d'un repositori.
Figura 1. Components d'un repositori de Git.
En la Figura 1 es distingeix l'Entorn de desenvolupament (Development Environment).
Aquesta part es troba localment en el teu dispositiu, on realitzes els canvis i desenvolupes el projecte.
D'una altra banda, hi ha el Repositori remot, que normalment s'allotja en un servidor accessible
per a tot l'equip de desenvolupament.
Dins de l'Entorn de desenvolupament hi ha els components següents:
Directori de treball (Working Directory): directori del sistema on s'emmagatzemen localment
els continguts del repositori.
Àrea de preparació (Staging Area): àrea que s'utilitza per a indicar quins canvis es volen confirmar.
Repositori local (Local Repository): repositori emmagatzemat localment on queden registrades
totes les versions i canvis dels fitxers, així com la informació de les branques i les etiquetes.
Quan treballes en un projecte de Git, els canvis es fan sobre el Directori de treball.
Aquests canvis poden ser:
Crear un fitxer nou: el fitxer comença en l'estat Untracked, és a dir, Git no en fa el seguiment.
Modificar un fitxer amb seguiment: el fitxer modificat passa a l'estat Modified.
Eliminar un fitxer amb seguiment: el fitxer eliminat passa a l'estat Deleted.
L'ordre git status mostra l'estat actual dels fitxers, i els tres estats anteriors apareixen de color roig.
Aquests canvis encara no formen part del repositori. Primer, cal afegir-los a l'Àrea de preparació
amb l'ordre git add, que canvia l'estat dels fitxers a Staged (de color verd en git status).
Finalment, tots els canvis de l'Àrea de preparació es confirmen i es fan efectius
en el Repositori local amb l'ordre git commit.
Figura 2. Flux de treball en un repositori de Git.
Per vore el flux de treball en la pràctica, s'afig el primer fitxer al repositori:
un fitxer README.md amb el contingut següent.
# 01 - Introducció a GitEstem aprenent a utilitzar Git!
jpuigcerver@fp:~/git_introduccio(main)$echo"# 01 - Introducció a Git">README.md
jpuigcerver@fp:~/git_introduccio(main)$echo"Estem aprenent a utilitzar Git!">>README.md
jpuigcerver@fp:~/git_introduccio(main)$catREADME.md
# 01 - Introducció a GitEstem aprenent a utilitzar Git!
Crea el fitxer README.md amb el contingut anterior en el directori git_introduccio.
Una vegada creat el fitxer, es comprova l'estat del repositori amb git status.
Git reconeix el fitxer nou, que ara mateix només es troba en el Directori de treball.
Com que encara no se'n fa el seguiment, el fitxer README.md es troba en l'estat Untracked.
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainNo commits yetUntracked files: (use "git add <file>..." to include in what will be committed)README.mdNothing added to commit but untracked files present (use "git add" to track)
Figura 3. Fitxer sense seguiment (untracked).
El pas següent és afegir els canvis a l'Àrea de preparació amb l'ordre git add,
que permet especificar quins canvis es volen incloure en el pròxim commit:
gitadd[--all]<path>
[--all]: (opcional) afegeix a l'Àrea de preparació tots els fitxers modificats i eliminats.
<path>: ruta del fitxer o directori que es vol afegir a l'Àrea de preparació.
jpuigcerver@fp:~/git_introduccio(main)$gitaddREADME.md
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainNo commits yetChanges to be committed: (use "git rm --cached <file>..." to unstage)new file: README.md
S'observa que el fitxer README.md ha passat a l'estat Staged i ja està preparat per a ser confirmat.
Si no s'especifica el missatge amb -m, s'obri l'editor per defecte(1) per a escriure el missatge del commit.
Per defecte és ViM, però es pot configurar:
gitconfig--globalcore.editor<editor>
Figura 5. Estat del repositori de Git abans de fer un commit.
Un commit és una instantània de l'estat dels fitxers del repositori en un moment concret,
que conté tota la informació relativa als canvis realitzats. Cada commit conté la informació següent:
Autor: persona que ha fet el commit.
Correu electrònic: correu electrònic de l'autor.
Data: data i hora en què s'ha fet el commit.
Missatge: descripció dels canvis realitzats en el commit.
Identificador o hash: codi únic generat automàticament que identifica el commit.
Canvis: llista de fitxers modificats, afegits o eliminats en el commit i els canvis realitzats
en cadascun respecte de la versió anterior.
Com que cada commit registra qui l'ha fet, abans del primer commit cal configurar
el nom i el correu electrònic de l'autor:
Amb aquesta informació configurada, ja es pot fer el primer commit.
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainNo commits yetChanges to be committed: (use "git rm --cached <file>..." to unstage)new file: README.mdjpuigcerver@fp:~/git_introduccio(main)$gitcommit-m"Added README.md"[main (root-commit) 8e70293] Added README.md 1 file changed, 2 insertions(+) create mode 100644 README.mdjpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainnothing to commit, working tree clean
S'observa que l'estat del repositori ha canviat i ja no hi ha canvis pendents de confirmar.
A més, s'ha creat el primer commit, amb el missatge Added README.md i l'identificador 8e70293.
Figura 6. Estat del repositori de Git després de fer un commit.
La informació del commit nou es pot consultar amb l'ordre git show:
jpuigcerver@fp:~/git_introduccio(main)$gitshow8e70293
commit 8e702933d5dbec9ee71100a1599ae4491085e1aa(HEAD->main)Author: Joan Puigcerver Ibáñez <j.puigcerveribanez@edu.gva.es>Date: Fri Oct 13 16:06:59 2023 +0200 Added README.mddiff --git a/README.md b/README.mdnew file mode 100644
index 0000000..6d747b3--- /dev/null+++ b/README.md@@ -0,0 +1,2 @@+# 01 - Introducció a Git+Estem aprenent a utilitzar Git!
L'ordre git diff permet comparar els canvis del Directori de treball o de l'Àrea de preparació
respecte del Repositori local. És molt útil per revisar què s'ha modificat abans de confirmar-ho.
La sintaxi amb les opcions bàsiques és:
gitdiff[--staged][<path>]
[--staged]: (opcional) mostra les diferències entre l'Àrea de preparació i el Repositori local.
Si no s'indica, compara el Directori de treball amb el Repositori local.
[<path>]: (opcional) fitxer o directori del qual es volen comparar les diferències.
Si no s'indica, es mostren totes les diferències.
index 6d747b3..f3b3b3e 100644: hash dels fitxers comparats i permisos.
--- a/README.md: ruta del fitxer original.
+++ b/README.md: ruta del fitxer modificat.
@@ -1,2 +1,3 @@: posició de les línies modificades.
-1,2: en el fitxer original, els canvis comencen en la línia 1 i afecten 2 línies.
+1,3: en el fitxer modificat, els canvis comencen en la línia 1 i afecten 3 línies.
A continuació, es mostren les línies modificades, precedides d'un símbol:
-: línia eliminada.
+: línia afegida.
En aquest cas, s'ha afegit la línia Aquesta és una línia nova al fitxer README.md.
Exemple: Diferències entre el Directori de treball i el Repositori local
S'afig una línia al fitxer README.md i es comparen el Directori de treball i el Repositori local.
jpuigcerver@fp:~/git_introduccio(main)$echo"Aquesta és una línia nova">>README.md
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainChanges 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: README.mdno changes added to commit (use "git add" and/or "git commit -a")jpuigcerver@fp:~/git_introduccio(main)$gitdiff
diff --git a/README.md b/README.mdindex 6d747b3..f3b3b3e 100644--- a/README.md+++ b/README.md@@ -1,2 +1,3 @@# 01 - Introducció a Git
Estem aprenent a utilitzar Git!
+Aquesta és una línia nova
S'observa la línia afegida, marcada amb el símbol +.
Exemple: Diferències entre l'Àrea de preparació i el Repositori local
S'afig el fitxer README.md a l'Àrea de preparació i es compara amb el Repositori local.
jpuigcerver@fp:~/git_introduccio(main)$gitaddREADME.md
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainChanges to be committed: (use "git restore --staged <file>..." to unstage)modified: README.mdjpuigcerver@fp:~/git_introduccio(main)$gitdiff--staged
diff --git a/README.md b/README.mdindex 6d747b3..f3b3b3e 100644--- a/README.md+++ b/README.md@@ -1,2 +1,3 @@# 01 - Introducció a Git
Estem aprenent a utilitzar Git!
+Aquesta és una línia nova
Com que els canvis ja són en l'Àrea de preparació, cal utilitzar l'opció --staged per a vore'ls.
L'ordre git restore permet descartar els canvis realitzats en els fitxers del Directori de treball
o de l'Àrea de preparació. És útil quan s'ha fet una modificació que no es vol conservar.
La sintaxi amb les opcions bàsiques és:
gitrestore[--staged]<path>
[--staged]: (opcional) trau els canvis de l'Àrea de preparació, però els manté en el
Directori de treball. Si no s'indica, es descarten els canvis del Directori de treball.
<path>: fitxer o directori del qual es volen descartar els canvis.
La Figura 2 resumeix el comportament de git restore.
L'ordre git restore descarta els canvis del Directori de treball sense possibilitat de recuperar-los.
Exemple: Descartar canvis en l'Àrea de preparació
Continuant amb l'exemple anterior, es trauen de l'Àrea de preparació els canvis del fitxer README.md.
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainChanges to be committed: (use "git restore --staged <file>..." to unstage)modified: README.mdjpuigcerver@fp:~/git_introduccio(main)$gitdiff--staged
diff --git a/README.md b/README.mdindex 6d747b3..f3b3b3e 100644--- a/README.md+++ b/README.md@@ -1,2 +1,3 @@# 01 - Introducció a Git
Estem aprenent a utilitzar Git!
+Aquesta és una línia novajpuigcerver@fp:~/git_introduccio(main)$gitrestore--stagedREADME.md
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainChanges 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: README.md
S'observa que el fitxer continua modificat, però ara els canvis només són en el Directori de treball.
Exemple: Descartar canvis en el Directori de treball
Es descarten els canvis realitzats en el fitxer README.md del Directori de treball.
Aquesta ordre descarta els canvis definitivament.
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainChanges 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: README.mdno changes added to commit (use "git add" and/or "git commit -a")jpuigcerver@fp:~/git_introduccio(main)$gitdiff
diff --git a/README.md b/README.mdindex 6d747b3..f3b3b3e 100644--- a/README.md+++ b/README.md@@ -1,2 +1,3 @@# 01 - Introducció a Git
Estem aprenent a utilitzar Git!
+Aquesta és una línia novajpuigcerver@fp:~/git_introduccio(main)$gitrestoreREADME.md
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainnothing to commit, working tree clean
S'observa que el repositori torna a estar net: la línia afegida s'ha perdut.
Es modifica novament el fitxer README.md i es fa un nou commit.
jpuigcerver@fp:~/git_introduccio(main)$echo"Aquesta és una altra línia">>README.md
jpuigcerver@fp:~/git_introduccio(main)$gitcommit-a-m"Added another line to README.md"# (1)![main c9fc6c8] Added another line to README.md 1 file changed, 1 insertions(+)
Amb -a s'afigen a l'Àrea de preparació els canvis del fitxer README.md sense necessitat de git add.
A continuació, es consulta l'històric de canvis amb git log.
jpuigcerver@fp:~/git_introduccio(main)$gitlog
commit c9fc6c856c2d52744b85a6f8d92feac496e60bd6(HEAD->main)Author: Joan Puigcerver Ibáñez <j.puigcerveribanez@edu.gva.es>Date: Mon Oct 16 11:43:20 2023 +0200 Added another line to README.mdcommit 8e702933d5dbec9ee71100a1599ae4491085e1aaAuthor: Joan Puigcerver Ibáñez <j.puigcerveribanez@edu.gva.es>Date: Fri Oct 13 16:06:59 2023 +0200 Added README.md
S'observa la informació de cada commit: l'autor, la data, el missatge i l'identificador.
L'ordre git log admet moltes opcions per a personalitzar com es mostren els commits i la seua informació.
Una possible combinació d'opcions per a visualitzar l'històric de manera més compacta i intuïtiva és:
Es mostra l'històric del repositori amb les opcions anteriors.
jpuigcerver@fp:~/git_introduccio(main)$gitlog--graph--abbrev-commit--decorate--format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)'*c9fc6c8-(2 minutes ago)Added another line to README.md-Joan Puigcerver(HEAD -> main)*8e70293-(3 days ago)Added README.md-Joan Puigcerver
S'observa que cada commit ocupa una sola línia.
No obstant això, no és pràctic recordar aquesta ordre. Per això, es pot configurar un àlies,
és a dir, un nom curt que Git substitueix per l'ordre completa:
Després de configurar l'àlies lg, n'hi ha prou amb executar git lg:
jpuigcerver@fp:~/git_introduccio(main)$gitlg
*c9fc6c8-(2 minutes ago)Added another line to README.md-Joan Puigcerver(HEAD -> main)*8e70293-(3 days ago)Added README.md-Joan Puigcerver
S'observa que el resultat és el mateix que en l'exemple anterior.
Aquesta ordre ja s'ha utilitzat per configurar els aspectes següents:
El nom (user.name) i el correu electrònic (user.email) de l'autor dels commits.
L'editor per defecte (core.editor).
Exemple: Consultar el nom i el correu electrònic configurats
Es consulten els valors de user.name i user.email en el nivell --global.
jpuigcerver@fp:~/git_introduccio(main)$gitconfig--globaluser.name
Joan Puigcerver Ibáñezjpuigcerver@fp:~/git_introduccio(main)$gitconfig--globaluser.email
j.puigcerveribanez@edu.gva.es
En lloc de modificar cada clau per separat, també es pot editar directament el fitxer de configuració
amb l'ordre git config --edit, que l'obri amb l'editor de text per defecte:
gitconfig[--local|--global|--system]--edit
[--local | --global | --system]: (opcional) nivell de configuració. Per defecte és --local.
Exemple: Fitxer de configuració de l'usuari (--global)
S'obri el fitxer de configuració del nivell --global.
[core]editor=code --wait# Editor per defecte[init]defaultBranch=main# Nom de la branca principal per defecte[user]name=Joan Puigcerver Ibáñezemail=j.puigcerveribanez@edu.gva.es[alias]lg = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)'lga=lg --all
S'observa tota la configuració feta fins ara, agrupada per seccions.
En un projecte hi ha fitxers que no s'han d'incloure en el repositori, com ara fitxers temporals,
binaris o fitxers de configuració local. Per això, Git permet ignorar fitxers mitjançant el fitxer
.gitignore, que conté una llista de patrons de fitxers que Git no ha de tindre en compte.
Aquest fitxer pot estar situat en qualsevol directori del repositori. Git ignora tots els fitxers
i subdirectoris d'aquest directori que complisquen algun dels patrons especificats.
Es crea el fitxer .gitignore amb els patrons següents:
.gitignore
# Ignora tots els fitxers .log
*.log
# Ignora tots els fitxers de qualsevol directori anomenat temp
temp/
A continuació, es comprova l'efecte d'ignorar el directori temp/.
jpuigcerver@fp:~/git_introduccio(main)$mkdirtemp
jpuigcerver@fp:~/git_introduccio(main)$touchtemp/file.txt
jpuigcerver@fp:~/git_introduccio(main)$gitstatus
On branch mainUntracked files: (use "git add <file>..." to include in what will be committed)temp/file.txtnothing added to commit but untracked files present (use "git add" to track)jpuigcerver@fp:~/git_introduccio(main)$echo"temp/">.gitignore
jpuigcerver@fp:~/git_introduccio(main)$gitstatus# (1)!On branch mainUntracked files: (use "git add <file>..." to include in what will be committed).gitignorenothing added to commit but untracked files present (use "git add" to track)
El fitxer temp/file.txt ja no apareix en l'estat del repositori després de crear el fitxer .gitignore.