Git
Chapters ▾ 2nd Edition

10.3 Git iznutra - Git reference

Git reference

Možete pokrenuti nešto kao git log 1a410e kako biste pregledali celu istoriju, ali i dalje morate da zapamtite da je 1a410e poslednji komit kako biste mogli da prošetate duž njegove istorije i pronađete sve ostale objekte. Potrebna vam je datotekea u kojoj ćete čuvati sve SHA-1 vrednost pod jednostavnim imenom kako biste mogli da koristite taj pokazivač umesto sirovih SHA-1 vrednosti.

U Gitu, ti objekti se nazivaju "reference" ili "refovi"; možete da nađete datoteke koje sadrže SHA-1 vrednosti u direktorijumu .git/refs. U trenutnom projektu, ovaj direktorijum ne sadrži datoteke, ali sadrži jednostavnu strukturu:

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

Kako biste kreirali novu referencu koja će vam pomoći da zapamtite gde se nalazi poslednji komit, možete da uradite nešto jednostavno kao što je ovo:

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

Sada možete da koristite referencu head koju ste kreirali umesto SHA-1 vrednosti u Git komandama:

$ git log --pretty=oneline  master
1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
cac0cab538b970a37ea1e769cbbde608743bc96d second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit

Ne savetuje se da neposredno menjate referencne datoteke. Git nudi sigurniju komandu koja radi ovo ako želite da ažurirate referencu, update-ref:

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

Ovo je u suštini grana u Gitu: jednostavan pokazivač ili referenca na glavu linije rada. Da biste kreirali granu na drugom komitu, možete da uradite ovo:

$ git update-ref refs/heads/test cac0ca

Vaša grana će sadržati samo rad počev od tog komita pa naniže:

$ git log --pretty=oneline test
cac0cab538b970a37ea1e769cbbde608743bc96d second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit

Sada vaša baza podataka u Gitu konceptualno izgleda nekako ovako:

Objekti iz Gitovog direktorijuma sa referencema na glave grana.
Figure 152. Objekti iz Gitovog direktorijuma sa referencema na glave grana.

Kada pokrećete komande kao što su git branch <ime-grane>], Git u suštini pokreće naredbu update-ref kako bi dodao SHA-1 poslednjeg komita grane na kojoj ste trenutno na koju god novu referencu želite da kreirate.

Referenca HEAD

Sada se postavlja pitanje: kada pokrenete git branch <ime-grane>], kako Git zna SHA-1 poslednjeg komita? Odgovor je u datoteci HEAD.

Datoteka HEAD je simbolična referenca na granu na kojoj se treutno nalazite. Pod simboličkom referencom mislimo na refencu koja, za razliku od običnih, u opštem slučaju ne mora da sadrži SHA-1 vrednost, već pokazivač na drugu referencu. Ako pogledate u datoteku, pod uobičajenim okolnostima ćete videti nešto ovako:

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

Ako pokrenete git checkout test, Git ažurira datoteku kako bi izgledala ovako:

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

Kada pokrenete git commit, kreira se novi komit-objekat, postavljajući roditelja tog komit-objekta da bude ona SHA-1 vrednost na koju pokazuje referenca u HEAD.

Možete i ručno da izmenite ovu datoteku; ali, opet, sigurnije je pokrenuti postojeću komandu symbolic-ref. Možete da pročitate podatke iz HEAD koristeći ovu komandu:

$ git symbolic-ref HEAD
refs/heads/master

Možete i da postavite vrednost HEAD.

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

Ovom komandom ne možete da podesite simboličku refenrencu na drugu referencu:

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

Tagovi

Upravo smo završili diskusiju o glavnim tipovima objekata, ali postoji i još jedan, četvrti. Tag-objekat dosta podseća na komit-objekat — sadrži podatke o osobi koja je dodala tag, datum, poruku i pokazivač. Glavna razlika je u tome što tag-objekat, u opštem slučaju, pokazuje na komit a ne na stablo. Podseća na granu, ali se nikad ne pomera — uvek pokazuje na isti komit, s tim što mu daje ime koje je lakše za pamćenje.

Kao što smo videli u poglavlu Osnove Gita, postoje dva tipa tagova: označeni i laki. Lake tagove možete da kreirate na sledeći način.

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

To je sve što se tiča lakog taga — obična referenca koja se nikad ne pomera. Označeni tag je, međutim, složeniji. Ako kreirate označenim tag, Git kreira tag-objekat i zatim piše refenecu koja će da pokazuje na njega umesto dirketno na komit. Ovo možete da vidite tako što ćete kreirati označen tag (zastavica -a ukazuje da se radi o označenom tagu).

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

Evo SHA-1 vrednosti objekta koji je kreiran:

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

Sada pokrenite komandu cat-file nad toj SHA-1 vrednosti.

$ 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

Primetite da stavke u objektu pokazuju na SHA-1 vrednost komita koji ste tagovali. Obratite pažnju i na to da nije potrebno da pokažete na komit; možete tagovati bilo koji Git objekat. U Gitovom izvornom kodu, na primer, developer je dodao svoj GPG javni ključ u blob objekat i onda ga tagovao. Možete pogledati javni ključ ako pokrenete ovo u svom klonu Gitovog repozitorijuma.

$ git cat-file blob junio-gpg-pub

I repozitorijum Linuksovog jezgra ima tagove koji ne pokazuju na komitove — prvi napravljeni tag pokazuje na inicijalno stablo uvezenog izvornog koda.

Udaljene reference

Treća vrsta referenci koju ćete vidđati su udaljene reference. Ako dodate udaljenu referencu i gurnete na nju, Git će čuvati vrednost koju ste poslednju gurnuli na tu referencu za svaku granu i direktorijumu refs/remotes. Na primer, možete dodati udaljenu referencu origin i gurnuti svoju master granu na nju.

$ 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

Možete videti šta je bila grana master na udaljenoj referenci remote poslednji put kada ste komunicirali sa serverom tako što ćete proveriti datoteku refs/remotes/origin/master:

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

Udaljene reference se razlikuju od grana (refs/heads refenrece) uglavnom po tome što su namenjene samo za čitanje. Možete da uradite get checkout nad nekom, ali Git neće postaviti HEAD na nju, tako da je nikad nećete ažurirati komandom git commit. Git rukuje njima kao obeleživačima koji ukazuju na poslednje poznato stanje tih grana na tim serverima.