Skip to content

Latest commit

 

History

History
188 lines (137 loc) · 7.98 KB

File metadata and controls

188 lines (137 loc) · 7.98 KB

Referències de Git

Si esteu interessat a veure l’historial del vostre repositori accessible des d’una confirmació, diguem, 1a410e, podríeu executar alguna cosa com git log 1a410e per mostrar aquest historial, però encara hauríeu de recordar que 1a410e és la confirmació que voleu utilitzar com a punt de partida per a aquest historial. En lloc d’això, seria més fàcil si tinguéssiu un fitxer on poguéssiu emmagatzemar aquest valor SHA-1 sota un nom simple perquè poguéssiu utilitzar aquest nom simple en lloc del valor SHA-1 brut.

A Git, aquests noms simples s’anomenen "referències" o "refs"; podeu trobar els fitxers que contenen aquests valors SHA-1 al directori .git/refs. Al projecte actual, aquest directori no conté fitxers, però sí que conté una estructura simple:

$ find .git/refs
.git/refs
.git/refs/heads
.git/refs/tags
$ find .git/refs -type f

Per crear una nova referència que us ajudi a recordar on és la vostra última confirmació, tècnicament podeu fer alguna cosa tan simple com això:

$ echo 1a410efbd13591db07496601ebc7a059dd55cfe9 > .git/refs/heads/master

Ara, podeu utilitzar la referència de cap que acabeu de crear en lloc del valor SHA-1 a les vostres comandes Git:

$ git log --pretty=oneline master
1a410efbd13591db07496601ebc7a059dd55cfe9 Third commit
cac0cab538b970a37ea1e769cbbde608743bc96d Second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d First commit

No se us anima a editar directament els fitxers de referència; en lloc d’això, Git proporciona la comanda més segura git update-ref per fer això si voleu actualitzar una referència:

$ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9

Això és bàsicament el que és una branca a Git: un simple punter o referència al cap d’una línia de treball. Per crear una branca al segon commit, podeu fer això:

$ git update-ref refs/heads/test cac0ca

La vostra branca només contindrà el treball des d’aquest commit cap avall:

$ git log --pretty=oneline test
cac0cab538b970a37ea1e769cbbde608743bc96d Second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d First commit

Ara, el vostre repositori Git conceptualment sembla alguna cosa així:

Git directory objects with branch head references included
Figure 1. Git directory objects with branch head references included

Quan executeu comandes com git branch <branch>, Git bàsicament executa aquesta comanda update-ref per afegir el SHA-1 de l’última confirmació de la branca en què esteu a qualsevol nova referència que vulgueu crear.

El HEAD

La pregunta ara és, quan executeu git branch <branch>, com sap Git el SHA-1 de l’última confirmació? La resposta és el fitxer HEAD.

Normalment el fitxer HEAD és una referència simbòlica a la branca en què esteu actualment. Per referència simbòlica, volem dir que, a diferència d’una referència normal, conté un punter a una altra referència.

No obstant això, en alguns casos rars, el fitxer HEAD pot contenir el valor SHA-1 d’un objecte Git. Això passa quan feu un checkout d’una etiqueta, confirmació o branca remota, cosa que posa el vostre repositori en estat de "detached HEAD".

Si mireu el fitxer, normalment veureu alguna cosa com això:

$ cat .git/HEAD
ref: refs/heads/master

Si executeu git checkout test, Git actualitza el fitxer per semblar-se a això:

$ cat .git/HEAD
ref: refs/heads/test

Quan executeu git commit, crea l’objecte de confirmació, especificant el pare d’aquest objecte de confirmació com a qualsevol valor SHA-1 al qual apunti la referència al HEAD.

També podeu editar manualment aquest fitxer, però de nou, existeix una comanda més segura per fer-ho: git symbolic-ref. Podeu llegir el valor del vostre HEAD a través d’aquesta comanda:

$ git symbolic-ref HEAD
refs/heads/master

També podeu establir el valor de HEAD utilitzant la mateixa comanda:

$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD
ref: refs/heads/test

No podeu establir una referència simbòlica fora de l’estil de refs:

$ git symbolic-ref HEAD test
fatal: Refusing to point HEAD outside of refs/

Etiquetes

Acabem de discutir els tres tipus principals d’objectes de Git (blobs, arbres i commits), però n’hi ha un quart. L’objecte etiqueta és molt semblant a un objecte commit: conté un etiquetador, una data, un missatge i un punter. La principal diferència és que un objecte etiqueta generalment apunta a un commit en lloc d’un arbre. És com una referència de branca, però mai es mou: sempre apunta al mateix commit però li dona un nom més amigable.

Com es va discutir a ch02-git-basics-chapter.asc, hi ha dos tipus d’etiquetes: anotades i lleugeres. Podeu crear una etiqueta lleugera executant alguna cosa com això:

$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d

Això és tot el que és una etiqueta lleugera: una referència que mai es mou. Una etiqueta anotada és més complexa, però. Si creeu una etiqueta anotada, Git crea un objecte etiqueta i després escriu una referència per apuntar-hi en lloc de directament al commit. Podeu veure això creant una etiqueta anotada (utilitzant l’opció -a):

$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'Test tag'

Aquí teniu el valor SHA-1 de l’objecte que ha creat:

$ cat .git/refs/tags/v1.1
9585191f37f7b0fb9444f35a9bf50de191beadc2

Ara, executeu git cat-file -p en aquest valor SHA-1:

$ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
object 1a410efbd13591db07496601ebc7a059dd55cfe9
type commit
tag v1.1
tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700

Test tag

Observeu que l’entrada de l’objecte apunta al valor SHA-1 del commit que vau etiquetar. També observeu que no necessita apuntar a un commit; podeu etiquetar qualsevol objecte Git. Al codi font de Git, per exemple, el mantenedor ha afegit la seva clau pública GPG com a objecte blob i després l’ha etiquetada. Podeu veure la clau pública executant això en un clon del repositori Git:

$ git cat-file blob junio-gpg-pub

El repositori del nucli de Linux també té un objecte etiqueta que no apunta a un commit: la primera etiqueta creada apunta a l’arbre inicial de la importació del codi font.

Remots

El tercer tipus de referència que veureu és una referència remota. Si afegiu un remot i feu push, Git emmagatzema el valor al qual vau fer push per última vegada a aquell remot per a cada branca al directori refs/remotes. Per exemple, podeu afegir un remot anomenat origin i fer push de la vostra branca master:

$ git remote add origin git@github.com:schacon/simplegit-progit.git
$ git push origin master
Counting objects: 11, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 716 bytes, done.
Total 7 (delta 2), reused 4 (delta 1)
To git@github.com:schacon/simplegit-progit.git
a11bef0..ca82a6d master -> master

Llavors, podeu veure quin era l’últim estat de la branca master al remot origin l’última vegada que vau comunicar-vos amb el servidor, comprovant el fitxer refs/remotes/origin/master:

$ cat .git/refs/remotes/origin/master
ca82a6dff817ec66f44342007202690a93763949

Les referències remotes difereixen de les branques (refs/heads) principalment en el fet que es consideren de només lectura. Podeu fer git checkout a una, però Git no referenciarà simbòlicament HEAD a una, així que mai l’actualitzareu amb una comanda commit. Git les gestiona com a marcadors de l’últim estat conegut d’on estaven aquestes branques en aquests servidors.