-
1. Başlanğıc
- 1.1 Versiyaya Nəzarət Haqqında
- 1.2 Git’in Qısa Hekayəsi
- 1.3 Git Nədir?
- 1.4 Əmr Sətiri
- 1.5 Git’i Quraşdırmaq
- 1.6 İlk Dəfə Git Quraşdırması
- 1.7 Kömək Almaq
- 1.8 Qısa Məzmun
-
2. Git’in Əsasları
-
3. Git’də Branch
- 3.1 Nutshell’də Branch’lar
- 3.2 Sadə Branching və Birləşdirmə
- 3.3 Branch İdarəedilməsi
- 3.4 Branching İş Axınları
- 3.5 Uzaq Branch’lar
- 3.6 Rebasing
- 3.7 Qısa Məzmun
-
4. Server’də Git
- 4.1 Protokollar
- 4.2 Serverdə Git Əldə Etmək
- 4.3 Sizin öz SSH Public Key’nizi yaratmaq
- 4.4 Server qurmaq
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Üçüncü Tərəf Seçimləri
- 4.10 Qısa Məzmun
-
5. Paylanmış Git
-
6. GitHub
-
7. Git Alətləri
- 7.1 Reviziya Seçimi
- 7.2 Interaktiv Səhnələşdirmə
- 7.3 Stashing və Təmizləmə
- 7.4 İşinizin İmzalanması
- 7.5 Axtarış
- 7.6 Tarixi Yenidən Yazmaq
- 7.7 Reset Demystified
- 7.8 İnkişaf etmiş Birləşmə
- 7.9 Rerere
- 7.10 Git ilə Debugging
- 7.11 Alt Modullar
- 7.12 Bundling
- 7.13 Dəyişdirmək
- 7.14 Etibarlı Yaddaş
- 7.15 Qısa Məzmun
-
8. Git’i Fərdiləşdirmək
- 8.1 Git Konfiqurasiyası
- 8.2 Git Atributları
- 8.3 Git Hook’ları
- 8.4 Git-Enforced Siyasət Nümunəsi
- 8.5 Qısa Məzmun
-
9. Git və Digər Sistemlər
- 9.1 Git Müştəri kimi
- 9.2 Git’ə Miqrasiya
- 9.3 Qısa Məzmun
-
10. Git’in Daxili İşləri
- 10.1 Plumbing və Porcelain
- 10.2 Git Obyektləri
- 10.3 Git Referansları
- 10.4 Packfile’lar
- 10.5 Refspec
- 10.6 Transfer Protokolları
- 10.7 Maintenance və Məlumatların Bərpası
- 10.8 Mühit Dəyişənləri
- 10.9 Qısa Məzmun
-
A1. Appendix A: Digər Mühitlərdə Git
- A1.1 Qrafik interfeyslər
- A1.2 Visual Studio’da Git
- A1.3 Visual Studio Code’da Git
- A1.4 Eclipse’də Git
- A1.5 Sublime Text’də Git
- A1.6 Bash’da Git
- A1.7 Zsh’də Git
- A1.8 PowerShell’də Git
- A1.9 Qısa Məzmun
-
A2. Appendix B: Proqramlara Git Daxil Etmək
- A2.1 Əmr-sətri Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Appendix C: Git Əmrləri
- A3.1 Quraşdırma və Konfiqurasiya
- A3.2 Layihələrin Alınması və Yaradılması
- A3.3 Sadə Snapshotting
- A3.4 Branching və Birləşmə
- A3.5 Layihələrin Paylaşılması və Yenilənməsi
- A3.6 Yoxlama və Müqayisə
- A3.7 Debugging
- A3.8 Patching
- A3.9 E-poçt
- A3.10 Xarici Sistemlər
- A3.11 İdarəetmə
- A3.12 Plumbing Əmrləri
10.6 Git’in Daxili İşləri - Transfer Protokolları
Transfer Protokolları
Git iki depo arasında məlumatları iki əsas şəkildə ötürə bilər: “dumb' protokolu və ``smart” protokolu. Bu bölmə bu iki əsas protokolun necə işlədiyini tez bir zamanda əhatə edəcəkdir.
The Dumb Protokolu
Yalnız bir oxunuşda HTTP üzərindən təqdim ediləcək bir depo qurursanız, dumb protokolundan istifadə edilməsi ehtimalı böyükdür.
Bu protokol “dumb” adlanır, çünki nəqliyyat prosesi zamanı server tərəfində Git-ə məxsus bir kod tələb olunmur; gətirmə prosesi, müştərinin serverdəki Git deposunun tərtibatını qəbul edə biləcəyi bir sıra HTTP GET
istəkləridir.
Note
|
Bu günlərdə dumb protokolu kifayət qədər nadir hallarda istifadə olunur. Təhlükəsizliyi təmin etmək və ya özəlləşdirmək çətindir, buna görə də Git host-larının əksəriyyəti (həm cloud əsaslı, həm də on-premises) istifadə etməkdən imtina edəcəkdir. Ümumiyyətlə bir azdan izah etdiyimiz daha ağıllı protokoldan istifadə etməyiniz tövsiyə olunur. |
Simplegit kitabxanası üçün http-fetch
prosesini izləyək:
$ git clone http://server/simplegit-progit.git
Bu əmrin ilk işi info/refs
faylını pull etməkdir.
Bu fayl update-server-info
əmri ilə yazılmışdır, bu səbəbdən HTTP nəqlinin düzgün işləməsi üçün bunu post-receive
hook olaraq təmin etməlisiniz:
=> GET info/refs
ca82a6dff817ec66f44342007202690a93763949 refs/heads/master
Artıq remote istinadların və SHA-1-lərin siyahısı var. Daha sonra, HEAD istinadının nə olduğunu axtarırsınız, belə ki bitirdikdən sonra nəyi yoxlayacağınızı biləcəksiniz:
=> GET HEAD
ref: refs/heads/master
Prosesi tamamladıqdan sonra master
branch-nı yoxlamalısınız.
Bu anda gəzinti prosesinə başlamağa hazırsınız.
Başlanğıc nöqtəniz info/refs
faylında gördüyünüz ca82a6
commit obyekti olduğundan, bunu əldə etməyə başlayırsınız:
=> GET objects/ca/82a6dff817ec66f44342007202690a93763949
(179 bytes of binary data)
Bir obyekt geri alırsınız – hanı ki, bu obyekt serverdə boş formatda olur və onu statik bir HTTP GET istəyi üzərinə götürmüşdünüz. Siz onu zlib-uncompress edə bilər, başlığı soyub, məzmuna baxa bilərsiniz:
$ git cat-file -p ca82a6dff817ec66f44342007202690a93763949
tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
parent 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
author Scott Chacon <schacon@gmail.com> 1205815931 -0700
committer Scott Chacon <schacon@gmail.com> 1240030591 -0700
Change version number
Sonra, sizin alacağınız daha iki obyektiniz var - yeni aldığımız commit-in göstərdiyi məzmun ağacından olan cfda3b
və valideyn olan 085bb3
:
=> GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
(179 bytes of data)
O sizə bir sonrakı obyekt commit-ini verir. Ağac obyektini götürün:
=> GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf
(404 - Not Found)
Oy! – belə görünür ki bu ağac obyekti serverdə boş formatda deyil, buna görə 404 cavabını geri alırsınız. Bunun bir neçə səbəbi ola bilər - obyekt alternativ bir depoda ola bilər və ya bu depodakı packfile-da da ola bilər. Git əvvəlcə siyahıda göstərilən alternativləri yoxlayır:
=> GET objects/info/http-alternates
(empty file)
Əgər o, alternativ URL-lərin siyahısı ilə geri qayıdırsa, Git boş faylları və packfile-ları yoxlayır - bu, bir-birinə çəngəllənən layihələrin diskdəki obyektləri paylaşması üçün gözəl bir mexanizmdir.
Bununla birlikdə, bu vəziyyətdə alternativlər göstərilmədiyindən, obyektiniz packfile-da olmalıdır.
Bu serverdə hansı packfile-ların mövcud olduğunu görmək üçün bunların siyahısını ehtiva edən (update-server-info
tərəfindən yaradılan) objects/info/packs
faylını əldə etməlisiniz.
=> GET objects/info/packs
P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
Serverdə yalnız bir packfile var, buna görə obyektiniz açıq-aydın şəkildə oradadır, ancaq əmin olmaq üçün indeks faylını yoxlayacaqsınız. Serverdə birdən çox packfile-nız varsa, bu da sizə lazım olan obyekti hansı packfile-da görə biləcəyiniz üçün faydalıdır:
=> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx
(4k of binary data)
Artıq packfile indeksinə sahib olduğunuzdan, obyektinizin içində olub olmadığını görə bilərsiniz - çünki indeks packfile-nızdakı obyektlərin SHA-1-lərini və həmin obyektlərin əvəzlərini siyahıya alır. Hədəfiniz oradadır, davam edin və bütün packfile-ı əldə edin:
=> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
(13k of binary data)
Indi sizin ağac obyektiniz mövcuddur və siz commit-lərinizi yeritməyə davam edə bilərsiniz.
Onların hamısı həm də hal-hazırda yüklədiyiniz packfile-da olduğundan serverə başqa request-lər göndərməyinizə ehtiyac yoxdur.
Git əvvəlində yüklədiyiniz HEAD arayışı ilə işarə edilən master
branch-ın işləyən bir nüsxəsini yoxlayır.
The Smart Protokolu
Dumb protokolu sadə, lakin bir az səmərəsizdir və müştəridən serverə məlumat yazmaqla işləyə bilmir. Smart protokolu daha çox məlumat ötürmə metodudur, lakin Git haqqında ağıllı bir proses tələb edir – o, yerli məlumatları oxuya bilir, müştərinin nəyə ehtiyac duyduğunu tapır və bunun üçün xüsusi bir paket yarada bilir. Məlumatların ötürülməsi üçün iki proses dəsti mövcuddur: uploading data üçün bir cüt və downloading data üçün bir cüt.
Uploading Data
Verilənləri remote prosesə yükləmək üçün Git, send-pack
və receive-pack
proseslərindən istifadə edir.
send-pack
prosesi müştəri üzərində işləyir və remote-dakı receive-pack
prosesinə qoşulur.
SSH
Məsələn, proyektinizdə git push origin master
işlətdiyinizi düşünək və origin
SSH protokolundan istifadə edən bir URL olaraq təyin olunduğunu deyək.
Git, SSH üzərindən serverinizə bir əlaqə quran send-pack
prosesini işə salır.
O, remote serverdə belə bir şeyə bənzəyən bir SSH çağırışı vasitəsilə bir əmr işlətməyə çalışır:
$ ssh -x git@server "git-receive-pack 'simplegit-progit.git'"
00a5ca82a6dff817ec66f4437202690a93763949 refs/heads/master□report-status \
delete-refs side-band-64k quiet ofs-delta \
agent=git/2:2.1.1+github-607-gfba4028 delete-refs
0000
git-receive-pack
əmri, hazırda sahib olduğu hər bir istinad üçün dərhal bir sətirlə cavab verir – yəni, bu halda yalnız master
branch-ı və onun SHA-1-i.
Birinci sətirdə serverin imkanlarının siyahısı (burada, report-status
, delete-refs
və digərləri, o cümlədən müştəri identifikatoru) var.
Məlumatlar chunk-lara ötürülür. Hər bir chunk, onun nə qədər olduğunu göstərən 4 simvollu bir hex dəyəri ilə başlayır (uzunluğun özünün 4 baytı da daxil olmaqla). Chunk-lar adətən tək bir məlumat sətri və arxadakı bir xətti qidalandırır. İlk chunk-nız 165 hexadecimal üçün 00a5 ilə başlayır, yəni chunk 165 bayt uzunluğundadır. Növbəti chunk 0000-dir, yəni server istinadlar siyahısı ilə hazırlanır.
Artıq serverin vəziyyətini bildiyindən, send-pack
prosesi, serverin etmədiyi commit-i müəyyənləşdirir.
Bu push-un yeniləyəcəyi hər istinad üçün, send-pack
prosesi bu məlumatı receive-pack
prosesinə izah edir.
Məsələn, master
branch-ı yeniləyirsinizsə və bir experiment
branch-na əlavə edirsinizsə, send-pack
cavabı belə görünə bilər:
0076ca82a6dff817ec66f44342007202690a93763949 15027957951b64cf874c3557a0f3547bd83b3ff6 \
refs/heads/master report-status
006c0000000000000000000000000000000000000000 cdfdb42577e2506715f8cfeacdbabc092bf63e8d \
refs/heads/experiment
0000
Git, xəttin uzunluğu, köhnə SHA-1, yeni SHA-1 və yenilənən istinadla yenilədiyiniz hər bir istinad üçün bir sətir göndərir. Birinci sətir də müştərinin imkanlarına malikdir. Bütün 0’ların SHA-1 dəyəri əvvəllər heç bir şey olmadığı demək deyil - çünki təcrübə istinadını siz əlavə edirsiniz. Əgər bir arayışı silsəniz, əksini görəcəksiniz: bütün '0-lar sağ tərəfdədir.
Sonra müştəri serverdə hələ mövcud olmayan bütün obyektlərin paketini göndərir. Nəhayət, server müvəffəqiyyət (və ya uğursuzluq) göstəricisi ilə cavab verir:
000eunpack ok
HTTP(S)
Bu proses əsasən HTTP-də də eynidir, baxmayaraq ki, qarşılıqlı əlaqə biraz fərqlidir. Əlaqə bu istəklə başladı:
=> GET http://server/simplegit-progit.git/info/refs?service=git-receive-pack
001f# service=git-receive-pack
00ab6c5f0e45abd7832bf23074a333f739977c9e8188 refs/heads/master□report-status \
delete-refs side-band-64k quiet ofs-delta \
agent=git/2:2.1.1~vmg-bitmaps-bugaloo-608-g116744e
0000
İlk müştəri-server mübadiləsi başa çatdı.
Müştəri daha sonra başqa bir sorğu göndərir, bu dəfə send-pack
-nin verdiyi məlumatlarla POST
göndərilir.
=> POST http://server/simplegit-progit.git/git-receive-pack
POST
sorğusuna, send-pack
output-u və packfile faydalı yük kimi daxildir.
Server daha sonra HTTP cavabı ilə müvəffəq və ya uğursuz olduğunu göstərir.
HTTP protokolunun bu məlumatları yığılmış köçürmə kodlaşdırmasının içərisinə əlavə edə biləcəyini unutmayın.
Downloading Data
Verilənləri yüklədiyiniz zaman, fetch-pack
və upload-pack
prosesləri iştirak edir.
Müştəri hansı məlumatların ötürüləcəyini müzakirə etmək üçün remote-dakı bir upload-pack
prosesinə qoşulan bir fetch-pack
prosesinə başlayır.
SSH
SSH üzərindən gətirmə edirsinizsə, fetch-pack
belə bir şey işlədir:
$ ssh -x git@server "git-upload-pack 'simplegit-progit.git'"
fetch-pack
qoşulduqdan sonra, upload-pack
geriyə belə bir şey göndərir:
00dfca82a6dff817ec66f44342007202690a93763949 HEAD□multi_ack thin-pack \
side-band side-band-64k ofs-delta shallow no-progress include-tag \
multi_ack_detailed symref=HEAD:refs/heads/master \
agent=git/2:2.1.1+github-607-gfba4028
003fe2409a098dc3e53539a9028a94b6224db9d6a6b6 refs/heads/master
0000
Bu, receive-pack
cavabları ilə çox oxşardır, lakin imkanları fərqlidir.
Bundan əlavə, HEAD-in işarə etdiyini geri göndərir (symref=HEAD:refs/heads/master
), buna görə müştəri bunun bir klon olub olmadığını yoxlayacağını bilir.
Bu nöqtədə, fetch-pack
prosesi hansı obyektlərə sahib olduğuna baxır və ehtiyac duyduğu obyektlərə “want” və sonra SHA-1 göndərərək cavab verir.
Artıq sahib olduğu bütün obyektləri “have” və sonra SHA-1 ilə göndərir.
Bu siyahının sonunda, ehtiyac duyduğu məlumatların paket sənədini göndərməyə başlamaq üçün upload-pack
prosesini başlamaq üçün “done” yazır:
003cwant ca82a6dff817ec66f44342007202690a93763949 ofs-delta
0032have 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
0009done
0000
HTTP(S)
Fetch əməliyyatı üçün əl sıxma iki HTTP request-i alır.
Birincisi, dumb protokolda eyni nöqtədə istifadə olunan bir GET
-dir:
=> GET $GIT_URL/info/refs?service=git-upload-pack
001e# service=git-upload-pack
00e7ca82a6dff817ec66f44342007202690a93763949 HEAD□multi_ack thin-pack \
side-band side-band-64k ofs-delta shallow no-progress include-tag \
multi_ack_detailed no-done symref=HEAD:refs/heads/master \
agent=git/2:2.1.1+github-607-gfba4028
003fca82a6dff817ec66f44342007202690a93763949 refs/heads/master
0000
Bu, SSH bağlantısı üzərindən git-upload-pack
çağırmağa çox oxşayır, lakin ikinci mübadilə ayrı bir istək olaraq həyata keçirilir:
=> POST $GIT_URL/git-upload-pack HTTP/1.0
0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7
0032have 441b40d833fdfa93eb2908e52742248faf0ee993
0000
Yenə də, bu yuxarıdakı ilə eyni formatdadır. Bu sorğunun cavabı müvəffəq və ya uğursuz olduğunu göstərir və paket sənədini də əhatə edir.
Protokolun Nəticəsi
Bu bölmə köçürmə protokollarının çox əsas bir icmalını ehtiva edir.
Protokolda multi_ack
və ya side-band
imkanları kimi bir çox digər xüsusiyyətlər var, lakin bunları əhatə etmək bu kitabın əhatə dairəsindən xaricdədir.
Sizə müştəri və server arasında ümumi geri və irəli bir fikir verməyə çalışdıq; bundan daha çox biliyə ehtiyacınız varsa, ehtimal ki, Git mənbə koduna nəzər yetirmək istərdiniz.