Git
Chapters ▾ 2nd Edition

7.12 Git Alətləri - Bundling

Bundling

Git məlumatlarını şəbəkə (HTTP, SSH və s.) üzərindən ötürməyin ümumi yollarını nəzərdən keçirsək də, ümumilikdə istifadə olunmayan, lakin olduqca faydalı ola biləcək daha bir yol var.

Git öz məlumatlarını vahid bir faylda “bundling” etməyə qadirdir. Bu müxtəlif ssenarilərdə faydalı ola bilər. Bəlkə şəbəkəniz itdi və iş yoldaşlarınıza dəyişikliklər göndərmək istəyirsiniz. Ola bilsin ki, başqa yerdə işləyirsiniz və təhlükəsizlik səbəbi ilə yerli şəbəkəyə qoşula bilmirsiniz. Bəlkə wireless / ethernet kartınız sadəcə qırılıb. Bəlkə bu anda ortaq bir serverə girmə imkanı yoxdur, kiməsə yeniləmələri e-poçtla göndərmək istəyirsiniz və 40 əmri format-patch vasitəsilə ötürmək istəmirsiniz.

git bundle əmrinin kömək edə biləcəyi yer məhz budur. bundle əmri, adətən git push əmri ilə telin üzərindən atılacaq hər şeyi, kiməsə e-poçt göndərə biləcəyiniz və ya bir flash sürücünüzə qoya biləcəyiniz və sonra başqa bir depoya daxil olaraq göndərə biləcəyiniz ikili sənədə yığacaqdır.

Sadə bir misala baxaq. Deyək ki, iki commit olan bir depo var:

$ git log
commit 9a466c572fe88b195efd356c3f2bbeccdb504102
Author: Scott Chacon <schacon@gmail.com>
Date:   Wed Mar 10 07:34:10 2010 -0800

    Second commit

commit b1ec3248f39900d2a406049d762aa68e9641be25
Author: Scott Chacon <schacon@gmail.com>
Date:   Wed Mar 10 07:34:01 2010 -0800

    First commit

Bu deponukiməsə göndərmək istəsəniz və push etmək üçün bir depo əldə edə bilmirsinizsə və ya sadəcə onu quraşdırmaq istəmirsinizsə, onu git bundle create ilə bağlaya bilərsiniz.

$ git bundle create repo.bundle HEAD master
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 441 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)

İndi repo.bundle adlı bir faylınız var ki, içində deponun əsas branch-ını yenidən yaratmaq üçün lazım olan bütün məlumatlar var. Bundle əmri ilə daxil olmasını istədiyiniz hər bir arayışı və ya bir sıra əmrləri siyahıya salmalısınız. Bunun başqa bir yerdə də klonlanmasını istəsəniz, burada etdiyimiz kimi bir məlumat olaraq HEAD əlavə etməlisiniz.

Bu repo.bundle faylını başqasına göndərə və ya USB sürücüsünə qoyub üzərindən keçə bilərsiniz.

Digər tərəfdən, bu repo.bundle faylı göndərdiyinizk və layihə üzərində işləmək istədiyinizi söyləyin. İkili fayldan bir URL-ə müraciət edə biləcək kimi bir qovluğu klonlaşdıra bilərsiniz.

$ git clone repo.bundle repo
Cloning into 'repo'...
...
$ cd repo
$ git log --oneline
9a466c5 Second commit
b1ec324 First commit

Əgər arayışlara HEAD daxil etmirsinizsə, -b master və ya hansı branch daxil edildiyini də göstərməlisiniz, çünki əks halda hansı branch-ın yoxlanılacağını bilməyəcək.

İndi deyək ki, üç tapşırığı yerinə yetirmisiniz və yeni əmrləri bir USB çubuğuna və ya e-poçtunuzdakı bir dəstə vasitəsilə geri göndərmək istəyirsiniz.

$ git log --oneline
71b84da Last commit - second repo
c99cf5b Fourth commit - second repo
7011d3d Third commit - second repo
9a466c5 Second commit
b1ec324 First commit

Əvvəlcə paketə daxil etmək istədiyimiz tapşırığı müəyyənləşdirməliyik. Şəbəkə üzərindən ötürülməsi üçün minimum məlumat toplusunu təyin edən şəbəkə protokollarından fərqli olaraq, bunu manual olaraq anlamalıyıq. İndi eyni şeyi edə bilər və işləyəcək bütün deponu bundle edə bilərsiniz, ancaq fərqləri yəni, yalnız local olaraq hazırladığınız üç əmri bundle etmək daha yaxşıdır.

Bunu etmək üçün fərqi hesablamalı olacaqsınız. Commit Aralıqları-da təsvir etdiyimiz kimi, bir sıra yollarla bir sıra tapşırıqları təyin edə bilərsiniz. Əvvəlcə klonlaşdırdığımız branch-da olmayan master branch-mızdakı üç əmri əldə etmək üçün origin/master..master və ya master ^origin/master kimi bir şeydən istifadə edə bilərik. Bunu log əmri ilə sınaya bilərsiniz.

$ git log --oneline master ^origin/master
71b84da Last commit - second repo
c99cf5b Fourth commit - second repo
7011d3d Third commit - second repo

Beləliklə, bundle-a daxil etmək istədiyimiz tapşırıqların siyahısı olduqdan sonra onları yığırıq. Bunu git bundle create əmri ilə edirik və ona bundle-mızın olmasını istədiyimiz bir ad verərək, daxil olmağımız lazım olan əmrlər sıra təqdim edirik.

$ git bundle create commits.bundle master ^9a466c5
Counting objects: 11, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (9/9), 775 bytes, done.
Total 9 (delta 0), reused 0 (delta 0)

İndi qovluğumuzda bir commits.bundle faylı var. Bunu götürüb ortağımıza göndərsək, o vaxt orada daha çox iş görülmüş olsa belə, onu orijinal depo içərisinə idxal edə bilər.

Bundle-ı aldıqda, onu depo içərisinə gətirmədən əvvəl nə olduğunu bilmək üçün yoxlaya bilər. Birinci əmr, sənədin doğrudan Git paketi olduğuna və onu düzgün şəkildə yenidən qurması üçün bütün lazımi soylarınıza sahib olduğundan əmin olacaq bundle verify əmridir.

$ git bundle verify ../commits.bundle
The bundle contains 1 ref
71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
The bundle requires these 1 ref
9a466c572fe88b195efd356c3f2bbeccdb504102 second commit
../commits.bundle is okay

Bundler, hər üçü deyil, yalnız son iki əmrdən ibarət bir dəstə yaratmış olsaydı, orijinal depo, lazımlı tarix olmadığı üçün onu idxal edə bilməzdi. Verify əmri bunun yerinə belə görünərdi:

$ git bundle verify ../commits-bad.bundle
error: Repository lacks these prerequisite commits:
error: 7011d3d8fc200abe0ad561c011c3852a4b7bbe95 Third commit - second repo

Hər şəkildə ilk bundle-mız etibarlıdır, ona görə də ondan əmr götürə bilərik. Bundle-da hansı branch-ların idxal edilə biləcəyini görmək istəyirsinizsə, yalnız head-ları sadalamaq üçün bir əmr var:

$ git bundle list-heads ../commits.bundle
71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master

verify alt komandası sizə head-ləri də xəbər verəcəkdir. Məsələ budur ki, nəyin pull edilə biləcəyini görmək üçün bu bundle-dan fetch və ya pull əmrlərini idxal əmrləri kimi istifadə edə bilərsiniz. Budur, bundle-ın master branch-nı depomuzdakı other-master adlı bir branch-a gətirəcəyik:

$ git fetch ../commits.bundle master:other-master
From ../commits.bundle
 * [new branch]      master     -> other-master

İndi görürük ki, idxal olunmuş əmrlərini other-master branch-ı ilə eyni zamanda öz master branch-mızda etdiyimiz hər hansı bir əmr var.

$ git log --oneline --decorate --graph --all
* 8255d41 (HEAD, master) Third commit - first repo
| * 71b84da (other-master) Last commit - second repo
| * c99cf5b Fourth commit - second repo
| * 7011d3d Third commit - second repo
|/
* 9a466c5 Second commit
* b1ec324 First commit

Beləliklə, git bundle sizin üçün müvafiq şəbəkə və ya bölüşdürülmüş depolarınız olmadıqda bölüşmək və ya şəbəkə tipli əməliyyatlar aparmaq üçün həqiqətən faydalı ola bilər.