Git
Chapters ▾ 2nd Edition

7.12 Orodja Git - Povezovanje v pakete

Povezovanje v pakete

Čeprav smo že pokrili pogoste načine prenosa podatkov Git preko omrežja (HTTP, SSH itd.), obstaja dejansko še en način, ki ni pogosto uporabljen, vendar je lahko zelo uporaben.

Git je sposoben svoje podatke »povezati« (angl. bundle) v eno datoteko. To je lahko uporabno v različnih scenarijih. Morda je vaše omrežje nedostopno, vendar želite poslati spremembe svojim sodelavcem. Morda delate nekje izven pisarne in nimate dostopa do lokalnega omrežja iz varnostnih razlogov. Morda se vam je pokvarila brezžična/ethernet kartica. Morda za zdaj nimate dostopa do skupnega strežnika, želite pa nekomu poslati posodobitve po e-pošti in ne želite prenesti 40 potrditev prek format-patch.

Tukaj je lahko koristen ukaz git bundle. Ukaz bundle bo vse, kar bi sicer bilo poslano po žici z ukazom git push, zapakiral v binarno datoteko, ki jo lahko pošljete po e-pošti, ali jo shranite na pomnilniški ključ, nato pa jo razpakirate v drugem repozitoriju.

Poglejmo si preprost primer. Recimo, da imate repozitorij s tremi potrditvami:

$ 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

Če želite ta repozitorij poslati nekomu in nimate dostopa do repozitorija, na katerega bi ga lahko potisnili, ali preprosto ne želite nastaviti novega, ga lahko zapakirate s pomočjo ukaza git bundle create.

$ 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)

Zdaj imate datoteko z imenom repo.bundle, ki vsebuje vse potrebne podatke za ponovno ustvarjanje veje master repozitorija. Pri uporabi ukaza bundle morate navesti vsako referenco ali določen obseg potrditev, ki jih želite vključiti. Če nameravate to uporabiti drugje, bi morali dodati kot referenco tudi glavo (HEAD), kot smo storili tukaj.

Datoteko repo.bundle lahko pošljete po e-pošti nekomu drugemu, ali pa jo shranite na ključ USB in jo odnesete drugam.

Po drugi strani, recimo, da ste prejeli datoteko repo.bundle in želite delati na projektu. Iz binarne datoteke lahko klonirate v mapo, podobno kot bi to storili iz URL-ja.

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

Če v reference ne vključite glave (HEAD), morate določiti tudi -b master ali katero koli drugo vejo, ki je vključena, saj v nasprotnem primeru Git ne bo vedel, katero vejo naj izvleče.

Recimo, da na njem naredite tri potrditve in želite nove potrditve poslati nazaj preko zbirke na ključu USB ali po e-pošti.

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

Najprej moramo določiti obseg potrditev, ki jih želimo vključiti v zbirko. V nasprotju z omrežnimi protokoli, ki sami ugotovijo minimalni nabor podatkov, ki jih je treba prenesti prek omrežja, bomo to morali ugotoviti ročno. Seveda lahko naredite enako stvar in v zbirko vključite celoten repozitorij, kar bo delovalo, vendar je bolje, da vključite le razliko — torej samo tri potrditve, ki smo jih ravnokar naredili lokalno.

Za to morate izračunati razliko. Kot smo opisali v Obsegi potrditev, lahko obseg potrditev določimo na več načinov. Da dobimo tri potrditve, ki jih imamo v naši veji master in ki jih ni bilo v veji, ki smo jo prvotno klonirali, lahko uporabimo nekaj takega, kot je origin/master..master ali master ^origin/master. To lahko preizkusite s pomočjo ukaza log.

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

Torej, zdaj, ko imamo seznam potrditev, ki jih želimo vključiti v zbirko, jih lahko zapakiramo vanjo. To naredimo s pomočjo ukaza git bundle create, pri čemer navedemo ime datoteke, v katero želimo shraniti svojo zbirko, in obseg potrditev, ki jih želimo vanjo vključiti.

$ 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)

Sedaj imamo datoteko commits.bundle v naši mapi. Če to datoteko pošljemo svojemu partnerju, jo lahko uvozi nazaj v prvotni repozitorij, tudi če je v tem času tam že bilo opravljenega več dela.

Ko prejme zbirko, lahko preveri, kaj vsebuje, preden jo uvozi v svoj repozitorij. Prva poteza je uporaba ukaza bundle verify, ki bo preveril, ali je datoteka dejansko veljavna zbirka Git in ali ima vse potrebne prednike za pravilno rekonstrukcijo.

$ 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

Če bi ustvarjalec zbirke ustvaril zbirko samo zadnjih dveh potrditev, ki jih je naredil, namesto vseh treh, prvotni repozitorij ne bi mogel uvoziti te zbirke, saj manjka potrebna zgodovina. Ukaz verify bi bil videti takole namesto tistega v prejšnjem primeru:

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

Vendar pa je naša prva zbirka veljavna, zato lahko iz nje pridobimo potrditve. Če želite videti, katere veje v zbirki se lahko uvozijo, obstaja tudi ukaz, ki navede le glave:

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

Podukaz verify vam bo prav tako povedal, katere glave so na voljo. Namen je videti, kaj lahko povlečete, zato lahko uporabite ukaza fetch ali pull, da uvozite potrditve iz te zbirke. Tukaj bomo pridobili vejo master zbirke v vejo imenovano other-master v našem repozitoriju:

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

Zdaj lahko vidimo, da imamo uvožene potrditve na veji other-master, skupaj s katerimi koli potrditvami, ki smo jih v tem času naredili na svoji lastni veji master.

$ 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

Tako lahko git bundle dejansko zelo koristi pri skupni rabi ali opravljanju operacij, podobnim mrežnim operacijam, ko nimate ustreznega omrežja ali skupnega repozitorija za to.

scroll-to-top