Jak na Git

V posledních pár měsících jsem se pral s verzovacím systémem Git. Teď už mám dojem, že jsem mu přišel na kloub, tak se chci podělit o to, jak se mi to povedlo. Snad to nezakřiknu.

Nakonec u mě zabral následující postup.

  1. Přečíst si knihu ProGit (anglicky nebo česky)
  2. Několik týdnu se pokoušet s Gitem pracovat, rvát si vlasy z hlavy, říkat si, že už jsem asi na ty počítače starý.
  3. Přečíst si knihu znovu a dosáhnout osvícení.

Rozhodně se tu nechystám Git popisovat, přečtěte si tu knihu. Jenom tu popíšu svůj mentální model toho, jak to celé pracuje. Musím vás varovat, že tento model se může lišit od reality, ale mě zatím pomáhá. Schválně budu ignorovat oblast změn (staging, index), budu se věnovat hlavně revizím, kolem kterých se všechno v Gitu točí.

Revize (alias snímek neboli commit) vznikne, když commitneme nějaké změny. Je důležité si uvědomit, že revize obsahuje obraz našeho projektu v okamžiku jejího vzniku. Takže to není popis rozdílů, ale opravdu snímek všech souborů tak jak v čase vytváření revize vypadaly. Interně to je samozřejmě pořešeno tak, aby to bylo rychlé a diskově nenáročné, navenek se ale Git opravdu tváří tak, že má hromadu snímků stavu projektu.

Každá taková revize má navíc jednoznačný identifikátor (hash) a také informaci o tom, které revize jí předcházely.

Toto už stačí, aby to všechno fungovalo. Máme hromadu revizí, které jsou uspořádány v jakémsi orientovaném grafu a my po tom grafu můžeme dle libosti skákat, dělat změny a vytvářet z nich nové revize. Abychom se v tom neztratili, mohou na jednotlivé revize ukazovat pojmenované identifikátory jako jsou větve a tagy. Je tu speciální identifikátor HEAD, který ukazuje na místo v grafu v které se právě nacházím. Všechny tyto identifikátory, ale nejsou nic jiného, než odkazy na revize.

Takže například kouzelný příkaz

git reset --hard <<revize>>

mi převede (téměř) všechny soubory v projektu do stavu v dané revizi a změní hodnotu odkazu HEAD. Tento příkaz si zapamatujte, ohromě se hodí, když se dostanete do potíží. Například když se vám nepovede merge a Git vám automaticky ty nepovedené změny commitne. Nemusíte mazat a naklonovat znovu celé úložištěm jako jsem to jednou v panice udělal já. Stačí se uklidnit, uvědomit si co je Git zač, najít číslo revize v které to bylo ještě v pořádku a vrátit se do ní. Docela bezpečné je vracet se do origin/master, to ukazuje na revizi, kde byl vrchol hlavní větve ve zdrojovém úložišti při poslední synchronizaci. Nepovedené změny sice někde v Gitu zůstanou hnít, ale to zas tak nevadí.

Toliko můj mentální model Gitu. Možná se ještě zmíním o tom, v čem se mi Git líbí. Zajímavé je například vyzobávání třešínek (cherrypick). To je funkce, která mi umožní vyzobnout si změny provedené v jedné revizi a aplikovat je na jinou revizi. Úžasná funkce, pokud potřebuje zároveň aplikovat jednu změnu do víc větví.

Mocná i když trochu nebezpečná zbraň je také přeskládání (rebase), které vám například umožní přehrát změny provedené v jedné větvi nad jinou větví. Dokonce vám to umožní přeházet pořadí revizí, slučovat revize dohromady, rozdělovat jednu revizi na víc atp. Ve skutečnosti se samozřejmě revize nemění, jenom se vytvoří nové, které se jen tváří jako ty původní s příslušnými změnami. Na přeskládání ale pozor, můžete tím naštvat své spolupracovníky, jejichž revize vycházejí z těch původních, nepřeskládaných.

Jinak mohu Git jen doporučit. Výsledek stojí za to, pokud přežijete dvojí přečtení jedné krátké knihy a čtrnáct dnů utrpení.

6 thoughts on “Jak na Git

  1. lzap

    Git je jedna z tech veci, u kterych si clovek rekne “Jak jen jsem mohl zit bez nej”. Kdyz pak musi chvili zase delat se Subversionem, tak to boli.

    Spise nez rebase bych jako nebezpecny prikaz oznacil prave hard reset (umi docela pekne “zahodit” praci a uz se s tim neda nic delat). Rebase je velmi sikovny, pouzivam jej denne a pomoci nej se da historie “stosovat” pekne do primky. Je to o mnoho lepsi nez zname “koleje” nebo “nadrazi”, kdyz na projektu dela vice vyvojaru a hodne merguji.

    ps – ja tu knihu cetl 3x 🙂

  2. Lukáš Křečan

    Cituji: “Git gets easier once you get the basic idea that branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space.”

  3. lzap

    Ten Successful Git branching model je pekny, ale na praci by nam to nestacilo. Rozlisujeme jeste tzv. “bugs” a “hotfixes”. Druha jmenovana vec je vlastne jen oprava chyby, ktera ma trosku jiny prubeh a provadi se obvykle backporting (cherry-picking). Je to pekne zpracovano, hezky clanek.

  4. martin

    Preco sa trapit s GITom, ktory polka vyvojoveho teamu poriadne nepochopi do konca projektu, a narobi viac skody nez uzitku, ked existuje “lightweight” varianta Mercurial? Zvlada myslim vsetky hlavne koncepty Gitu, s rozumnou urovnou frustracie pre novacikov 🙂

  5. Lukáš Křečan

    Musím se přiznat, že jsem měl s Mercurialem podobné problémy.

Comments are closed.