Git
Chapters ▾ 2nd Edition

10.3 Notranjost Gita - Reference Git

Reference Git

Če vas zanima ogled zgodovine vašega repozitorija, katera je dosegljiva od potrditve 1a410e, bi lahko zagnali nekaj podobnega kot git log 1a410e, da bi prikazali to zgodovino, vendar bi si še vedno morali zapomniti, da je 1a410e tista potrditev, ki jo želite uporabiti kot začetno točko za to zgodovino. Namesto tega bi bilo lažje, če bi imeli datoteko, v kateri bi lahko shranili tisto vrednost SHA-1 pod preprostim imenom, tako da bi lahko uporabili to preprosto ime namesto surove vrednosti SHA-1.

V Gitu se ta preprosta imena imenujejo »reference« ali »refs«; datoteke, ki vsebujejo te vrednosti SHA-1, lahko najdete v imeniku .git/refs. V trenutnem projektu ta imenik ne vsebuje datotek, vendar vsebuje preprosto strukturo:

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

Da ustvarite novo referenco, ki si vam bo pomagala zapomniti, kje je vaša zadnja potrditev, lahko teoretično naredite nekaj tako preprostega kot to:

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

Sedaj lahko v svojih ukazih Git uporabite glavno referenco, ki ste jo pravkar ustvarili namesto vrednosti SHA-1:

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

Ne spodbujamo vas, da neposredno urejate datoteke z referencami; namesto tega Git ponuja varnejši ukaz git update-ref, če želite posodobiti referenco:

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

To je v bistvu tisto, kar je veja v Gitu: preprost kazalnik ali referenca na konico delovne veje. Če želite ustvariti vejo nazaj pri drugi potrditvi, lahko to storite takole:

$ git update-ref refs/heads/test cac0ca

Vaša veja bo vsebovala samo delo od tiste potrditve navzdol:

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

Sedaj je vaša podatkovna baza Git konceptualno videti nekako takole:

Objekti direktorija Git, ki vključujejo glavne reference veje
Slika 176. Objekti direktorija Git, ki vključujejo glavne reference veje

Ko zaženete ukaze, kot je git branch <branch>, Git v bistvu zažene ukaz update-ref, da doda SHA-1 zadnje potrditve vaše trenutne veje v katero koli novo referenco, ki jo želite ustvariti.

HEAD

Vprašanje je zdaj, kako Git ve za SHA-1 zadnje potrditve, ko zaženete git branch <branch>? Odgovor je datoteka HEAD.

Običajno je datoteka HEAD simbolična referenca na trenutno vejo. S simbolično referenco mislimo, da vsebuje kazalec na drugo referenco, v nasprotju z običajno referenco.

Vendar pa v nekaterih redkih primerih datoteka HEAD vsebuje vrednost SHA-1 objekta Git. To se zgodi, ko izvlečete oznako, potrditev, ali oddaljeno vejo, kar postavi vaš repozitorij v stanje ločene glave.

Če pogledate datoteko, boste običajno videli nekaj takega:

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

Če poženete git checkout test, bo Git posodobil datoteko, da je videti nekako takole:

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

Ko zaženete git commit, to ustvari objekt potrditve in določi nadrejeno tega objekta potrditve na vrednost SHA-1, na katero referenca v datoteki HEAD kaže.

Datoteko lahko uredite tudi ročno, vendar obstaja tudi tukaj varnejši ukaz, ki to omogoča: git symbolic-ref. Vrednost datoteke HEAD lahko preberete s tem ukazom:

$ git symbolic-ref HEAD
refs/heads/master

Z uporabo istega ukaza lahko tudi nastavite vrednost HEAD:

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

Simbolične reference izven stila referenc ne morete nastaviti:

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

Oznake

Ravno smo končali razpravo o treh glavnih vrstah objektov v Gitu (blobi, drevesa in potrditve), vendar obstaja še četrti objekt. Objekt oznake je zelo podoben objektu potrditve — vsebuje označevalca, datum, sporočilo in kazalec. Glavna razlika je v tem, da oznaka običajno kaže na potrditev namesto na drevo. Podobna je referenci na vejo, vendar se nikoli ne premika — vedno kaže na isto potrditev, vendar mu da prijaznejše ime.

Kot smo razpravljali v Osnove Git, obstajata dve vrsti oznak: anotirane in enostavne. Enostavno oznako lahko ustvarite z zagonom nečesa takega:

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

To je vse, kar je lahko enostavna oznaka — referenca, ki se nikoli ne premika. Anotirana oznaka pa je bolj zapletena. Če ustvarite anotirano oznako, Git ustvari objekt oznake in nato zapiše referenco, da kaže nanjo namesto neposredno na potrditev. To lahko vidite, če ustvarite anotirano oznako (z uporabo možnosti -a):

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

Tu je vrednost SHA-1 objekta, ki ga to ustvari:

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

Sedaj poženite git cat-file -p na tej vrednosti 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

Opazite, da vnos objekta kaže na vrednost SHA-1 potrditve, ki ste jo označili. Prav tako opazite, da ni potrebno, da kaže na potrditev; lahko označite kateri koli objekt Git. V izvorni kodi Git je na primer vzdrževalec dodal svoj javni ključ GPG kot objekt blob in ga nato označil. Javni ključ si lahko ogledate tako, da v klonu repozitorija Git zaženete to:

$ git cat-file blob junio-gpg-pub

Tudi repozitorij jedra Linux ima objekt oznake, ki ne kaže na potrditev — prva ustvarjena oznaka kaže na začetno drevo uvoza izvorne kode.

Daljave

Tretja vrsta reference, ki jo boste videli, je oddaljena referenca. Če dodate oddaljeni vir in nanj potisnete, Git shrani vrednost, ki ste jo nazadnje potisnili na ta oddaljeni vir za vsako vejo v mapi .git/refs/remotes. Na primer, lahko dodate oddaljeni vir, imenovan origin, in nanj potisnete svojo vejo 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

Nato pa lahko preverite, katera različica veje master na oddaljenem strežniku origin je bila nazadnje poslana, tako da preverite datoteko refs/remotes/origin/master:

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

Oddaljene reference se razlikujejo od vej (reference refs/heads) predvsem v tem, da so obravnavane kot samo za branje. Z git checkout se jih lahko izvleče, vendar Git ne bo simbolno referenciral HEAD nanje, zato jih nikoli ne boste posodobili z ukazom commit. Git jih upravlja kot zaznamke zadnjega znanega stanja, kjer so bile te veje na teh strežnikih.

scroll-to-top