Git
Chapters ▾ 2nd Edition

10.3 Git’in Daxili İşləri - Git Referansları

Git Referansları

Deponuzun tarixini qeydiyyat prosesindən, məsələn 1a410e kimi görmək mümkündürsə, bu tarixçəyə baxmaq üçün git log 1a410e kimi bir şey işlədə bilərsiniz, amma yenə də 1a410e-nin bu tarix üçün başlanğıc nöqtəsi olaraq istifadə etmək istədiyiniz commit prosesi olduğunu unutmamalısınız. Bunun əvəzinə, həmin SHA-1 dəyərini sadə bir ad altında saxlaya biləcəyiniz bir faylınız olsaydı daha asan olardı, belə ki, xam SHA-1 dəyərindən çox bu sadə addan istifadə edə bilərsiniz.

Git-də bu sadə adlara references'' və ya ``refs'' deyilir; həmin SHA-1 dəyərlərini ehtiva edən sənədləri `.git/refs qovluğunda tapa bilərsiniz. Mövcud layihədə bu qovluqda heç bir fayl yoxdur, ancaq sadə bir quruluş içərisindədir:

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

Ən son commit-nizin harada olduğunu xatırlamağa kömək edəcək yeni bir istinad yaratmaq üçün texniki olaraq bu qədər sadə bir şey edə bilərsiniz:

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

İndi Git əmrlərinizdəki SHA-1 dəyəri əvəzinə yeni yaratdığınız head referansından istifadə edə bilərsiniz:

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

Referans fayllarını birbaşa redaktə etməyiniz tövsiyə edilmir; Bunun əvəzinə, Git, bir referansı yeniləmək istəyirsinizsə, bunu etmək üçün daha təhlükəsiz git update-ref əmrini istifadə edə bilərsiniz:

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

Əsasən Gitdəki bir branch budur: sadə bir göstərici və ya bir iş xəttinin rəhbərinə referans. İkinci commit-də bir branch yaratmaq üçün bunu edə bilərsiniz:

$ git update-ref refs/heads/test cac0ca

Branch-ınızda yalnız aşağıda sadalananların işi olacaq:

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

İndi Git verilənlər bazanız konseptual olaraq belə görünür:

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

git branch <branch> kimi əmrləri işə saldığınız zaman Git əsasən yaratmaq istədiyiniz hər hansı bir faylın son commit-i olan SHA-1-i əlavə etmək üçün update-ref əmrini işə salır.

HEAD

İndi sual, git branch <branch> işlətdiyiniz zaman Git sonuncu commit-dən SHA-1-i necə bilir? Cavab HEAD faylıdır.

Ümumiyyətlə HEAD faylı, hazırda olduğunuz branch-a simvolik bir referansdır. Simvolik istinad dedikdə, normal bir istinaddan fərqli olaraq başqa bir istinad üçün bir göstərici ehtiva etdiyini nəzərdə tuturuq.

Lakin bəzi nadir hallarda HEAD faylında git obyektinin SHA-1 dəyəri ola bilər. Deponuzu "detached HEAD" vəziyyətinə qoyan bir etiket, commit və ya uzaq bir branch-ı çıxardıqda bu baş verir.

Fayla baxsanız, normal olaraq belə bir şey görəcəksiniz:

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

git checkout test işlətsəniz, Git faylını belə görünmək üçün yeniləyir:

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

git commit əmrini işlətdiyinizdə, commit obyektinin əsas hissəsinin HEAD-dəki referansının işarə etdiyi SHA-1 dəyəri olduğunu ifadə edərək, commit obyektini yaradır.

Bu faylı manual olaraq da düzəldə bilərsiniz, lakin bunun üçün daha etibarlı bir əmr mövcuddur: git symbolic-ref. HEAD-in dəyərini bu əmr vasitəsilə oxuya bilərsiniz:

$ git symbolic-ref HEAD
refs/heads/master

Eyni əmrdən istifadə edərək HEAD dəyərini də təyin edə bilərsiniz:

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

Referans üslubundan kənarda simvolik bir istinad təyin edə bilməzsiniz:

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

Tags

Git’in üç əsas obyekt növünü (blobs, treescommits) müzakirə etməyi bitirdik, indi dördüncüsünə baxaq. Tag obyekti bir commit obyektinə çox oxşayır - etiket, tarix, mesaj və göstərici ehtiva edir. Əsas fərq odur ki, bir etiket obyekti ümumiyyətlə bir ağaca deyil, bir commit-ə işarə edir. Bu branch referansına bənzəyir, amma heç vaxt tərpənmir - həmişə eyni commit-i göstərir, lakin ona daha dost bir ad verir.

Git’in Əsasları-də müzakirə edildiyi kimi iki növ etiket var: izahatlı və yüngül. Belə bir şey işlədərək yüngül bir etiket edə bilərsiniz:

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

Bütün bunlar yüngül bir etiketdir - heç vaxt hərəkət etməyən bir referans. Şərhli etiket daha mürəkkəbdir. İzahatlı bir etiket yaratsanız, Git bir etiket obyekti yaradır və sonra birbaşa commit-ə deyil, ona işarə etmək üçün bir referans yazır. Bunu izahatlı bir etiket yaratmaqla görə bilərsiniz (-a seçimindən istifadə edərək):

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

Yaratdığı obyekt SHA-1 dəyəri budur:

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

İndi SHA-1 dəyərində git cat-file -p işlədin:

$ 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

Nişan girişinin etiketlədiyiniz SHA-1 dəyərini göstərdiyinə diqqət yetirin. Bir commit-i göstərməyə ehtiyac olmadığına da diqqət yetirin; istənilən Git obyektini etiketləyə bilərsiniz. Məsələn, Git qaynaq kodunda qoruyucu GPG ümumi açarını bir blob obyekti olaraq əlavə etdi və sonra etiketlədi. Bunu Git deposunun bir klonunda işlədərək ümumi açara baxa bilərsiniz:

$ git cat-file blob junio-gpg-pub

Linux kernel deposunda ayrıca bir işarə etməyən bir etiket obyekti var - ilk etiket mənbə kodunun idxalının başlanğıc ağacına nöqtələr yaratdı.

Remote-lar

Görəcəyiniz üçüncü reefrans növü remote bir referansdır. Bir remote əlavə edib ona push etsəniz, Git bu məsafəyə son göndərdiyiniz dəyəri hər bir branch üçün refs/remotes qovluğunda saxlayır. Məsələn, origin adlı bir remote əlavə edə və master branch-ınızı ona push edə bilərsiniz:

$ 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

Daha sonra refs/remotes/origin/master faylını yoxlayaraq server ilə son əlaqə qurduğunuz mənbə remote-undakı master branch-ının nə olduğunu görə bilərsiniz:

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

Uzaqdan referanslar branch-lardan (refs/heads referansları) əsasən read-only sayılmaları ilə fərqlənir. Birinə git checkout edə bilərsiniz, ancaq Git HEAD-i birinə yönəltməyəcək, buna görə onu heç bir zaman commit əmri ilə yeniləməyəcəksiniz. Git onları bu branch-ların həmin serverlərdə olduğu son bilinən vəziyyətə qədər bookmark-lar kimi idarə edir.