Linux: Kniha kouzel, vanilková příchuť 2.14 (15. července 2022)
Veškerá moc příkazové řádky/příkazového řádku přehledně, pro začátečníky i pokročilé
5. Git
Řada 2.x vanilkové příchuti Linuxu: Knihy kouzel je od 15. července 2022
do 1. března 2025 ve stavu dlouhodobé pasivní údržby;
nahlášené chyby budou opravovány, ale aktivní vývoj se již věnuje jiným
projektům. Máte-li zájem pokračovat v tvorbě Linuxu: Knihy kouzel
pro novější verze linuxových operačních systémů,
kontaktujte autora nebo rovnou vytvořte odnož.
Git je široce používaný systém správy verzí.
Je používán k verzování zdrojových kódů nebo jiných skupin textových souborů.
Umožňuje snadný přístup do historie verzovaných souborů a slučování změn provedených
odděleně, často mnoha různými uživateli.
Příklad architektury repozitářů v Gitu:
Tato verze kapitoly nepokrývá práci s podrepozitáři (submodules).
Příkaz „git stash“ je pokryt částečně, příkaz „git rebase -i“ pokryt není.
Pracovní adresář (PA) je adresář, který obsahuje soubory verzované Gitem v otevřené podobě, abyste s nimi mohli přímo pracovat. Vždy přísluší k určitému místnímu repozitáři.
Ke každému PA příluší jedna přípravná oblast (PO, anglicky „staging area“ či „index“), což je skrytá oblast, ve které přenášením změn z PA vzniká nová revize.
Revize je konkrétní neměnný (historický) stav verzovaných souborů v PA, označený a doplněný o další údaje (zejména datum, čas, komentář a označení přispěvatele).
Když do repozitáře vložíte novou revizi, předchozí revize se stane rodičem nově vložené revize. Většina revizí má jednoho rodiče; výjimkou jsou kořenové revize, které nemají žádné rodiče, a revize vzniklé slučováním změn („spojováním vývojových větví“), které mají obvykle dva rodiče (vzácně i víc).
Předkové revize X jsou její rodiče, rodiče rodičů a tak dále. Nejbližší společný předek (NSP) dvou revizí je: 1) Pokud je jedna z revizí předkem té druhé, pak je NSP ona. 2) Jinak je NSP, pokud existuje, taková revize, která je společným předkem obou revizí, ale není rodičem žádné revize, která by společným předkem obou revizí byla také.
Větev (branch) je v Gitu proměnný odkaz na (nejnovější) revizi. Když vytvoříte novou revizi, aktivní větev se automaticky nastaví tak, aby na tuto novou revizi odkazovala. Můžete mít mnoho různých větví, každou nechat odrážet jiný směr vývoje a přepínat se mezi nimi.
Jméno revize (tag) je trvalé a neměnné symbolické označení určité revize v repozitáři (něco jako konstanta). Obvykle se používá k označení význačných revizí, např. těch, ze kterých vznikla vydaná verze softwaru.
Aktivní větev je pro daný PA větev, která do něj byla naposledy načtena a k níž je připojen – to znamená, že nově vzniklé revize budou do dané větve přiřazovány. Pokud je PA odpojený od větve, má místo aktivní větve pouze aktivní revizi. Aktivní větev (případně aktivní revize) se symbolicky označuje HEAD.
Vzdálená větev není větev ve výše uvedeném významu, ale jde o kopii větve ze vzdáleného repozitáře v místním repozitáři, která je aktualizována příkazem „git fetch“ nebo „git pull“.
Repozitář je úložiště revizí. V Gitu se setkáte se třemi druhy repozitářů:
Místní repozitář je nejčastější. Může spolupracovat se vzdálenými repozitáři a má k sobě vždy jeden hlavní PA; můžete k němu vytvářet také vedlejší PA. Místní repozitář může sloužit jako vzdálený repozitář jiného místního repozitáře, ale pouze ke čtení – nelze do něj odesílat.
Holý repozitář nemá vlastní pracovní adresáře; slouží především v roli vzdáleného repozitáře pro místní repozitáře.
Máte-li místní repozitář, jako vzdálené repozitáře se označují oddělené repozitáře, ke kterým je místní repozitář připojen a může z nich čerpat revize a větve, případně je do nich i odesílat. Vzdálené repozitáře se mohou nacházet v místním souborovém systému nebo být dostupné přes síť a samy o sobě to mohou být holé nebo (méně často) místní repozitáře.
V Gitu se používá několik způsobů, jak můžete v příkazech označovat jednotlivé revize:
Úplná SHA-1 heš je vhodná pouze ve skriptech, na ruční použití je nepraktická.
Jednoznačná předpona heše je vhodná pro ruční použití; v malých projektech obvykle stačí první tři znaky, ve velkých pět nebo šest. Pokud předpona není jednoznačná, Git ohlásí chybu.
Symbolické označení, např. název větve, jméno revize nebo „HEAD“.
Za jakýmkoliv označením revize můžete (i opakovaně a v kombinaci) použít tyto dva operátory:
Stříška „^“ znamená přechod na rodiče revize, takže např. „HEAD^^“ znamená rodič rodiče aktivní revize. Pro přechod na jiného než prvního rodiče zadejte za stříšku číslo, takže např. „HEAD^2“ znamená přechod na druhého rodiče aktivní revize.
Tilda (např. „\~2“) znamená N opakování operátoru „^“. Např. „\~3“ je zkratka za „^^^“, tedy rodič rodiče rodiče revize. (Zpětné lomítko se zde používá kvůli odzvláštnění v bashi; alternativní možností je uzavření označení revize do uvozovek, např. „"HEAD~2"“.)
(globální parametr) Před vykonáním příkazu vstoupí do zadaného adresáře.
git [globální parametry] commit [parametry]
-a
Před vytvořením revize přenese do PO všechny změny a smazání verzovaných souborů v pracovním adresáři. Neverzované soubory nepřidává.
-m "komentář"
Použije k revizi uvedený komentář a neotevře editor.
--amend
Nahradí stávající aktivní revizi, přičemž nové revizi zůstane čas, označení přispěvatele a komentář z původní revize, pokud nepoužijete v kombinaci s parametrem „--reset-author“.
--allow-empty
Dovolí vložit novou revizi i v případě, že PO neobsahuje žádné změny oproti HEAD.
--no-edit
Potlačí vyvolání editoru k zadání komentáře ke commitu.
git [globální parametry] add [parametry]
-u
Přenese do indexu jen změny ve verzovaných souborech a jejich smazání, nepřidává nové soubory k verzování.
Celé jméno a e-mail se používají k označení autorství revizí.
Musíte je zadat z každého uživatelského účtu, kde budete Git používat,
odmítne pracovat a vyzve vás k jejich nastavení. (Nemusíte je ovšem zadat pravdivě.)
Globálně zadané hodnoty můžete pro jednotlivé repozitáře změnit.
Soubor .gitignore může být v každém podadresáři PA; jeho deklarace platí v adresáři, kde se nachází, a ve všech jeho podadresářích.
Vytvoříte-li v podadresáři pracovního adresáře soubor „.gitignore“ obsahující jediný řádek „*“, git bude tento adresář a veškerý jeho další obsah zcela ignorovat. To je praktické, když chcete mít v pracovním adresáři podadresář, který nikdy nebudete chtít verzovat.
Soubor „.gitignore“ se obvykle verzuje spolu s normálními soubory.
Příkaz „git merge revize“ najde NSP aktivní větve a zadané revize
a pokusí se do aktivní větve sloučit všechny změny od tohoto předka do „revize“.
(To mimochodem znamená, že je-li revize předkem aktivní větve, neudělá příkaz nic, a je-li
naopak potomkem, aktivní větev se jednoduše nastaví na zadanou revizi.)
Git se při slučování snaží všechny změny zanést automaticky. Pokud jsou však změny v některých
souborech konfliktní, automatické slučování selže a konflikty musíte vyřešit ručně,
příkazem „git mergetool“ nebo slučování zrušit příkazem „git merge --abort“.
Zde vysvětlím pouze ruční řešení konfliktů. Příkazem „git status“ identifikujte soubory,
kde se konflikty nacházejí (jsou označené „both modified“). Každý takový soubor musíte
otevřít v textovém editoru a najít konflikty (Git je označil příslušnými značkami).
Řádky, které jsou v konfliktu, musíte nějakým rozumným způsobem sloučit, a značky Gitu
odstranit. Po vyřešení všech konfliktů odešlete změny do PO a vytvořte revizi:
git add -u && git commit --no-edit
Pozor, pokud značky konfliktu někde zapomenete, zůstanou součástí příslušných souborů,
což může být do budoucna problém.
Další dobrou možností je oficiální online referenční příručka (viz sekci „Odkazy“),
ale vždy budete muset zkontrolovat, zda vaše verze Gitu uváděné volby již podporuje.
Přehled podporovaných konfiguračních voleb pro příkaz „git config“ najdete
(v angličtině) v online referenční příručce u příkazu „git config“.
1 Vhodné formáty jsou „medium“, „oneline“ a „reference“; vyzkoušejte, který z nich vám víc vyhovuje. Úplný popis k revizím z nich poskytuje jen „medium“.
3 Při bezpečném mazání Git odmítne smazat větev, pokud by tím přestaly být dostupné některé revize, protože nejsou odkazovány odjinud. Bezpečné mazání je tedy určeno především pro mazání větví, jejichž změny již byly sloučeny do jiných větví.
4 Po přiřazení nové revize aktivní větvi vám zdánlivě v PO vzniknou nové změny, protože PO zůstane ve stavu odpovídajícím původní revizi. Pokud se chcete veškerých odlišností PO a PA od cílové revize zbavit, místo „--soft“ použijte „--hard“.
5 Místo uvedeného tvaru příkazu „git commit“ můžete použít jakýkoliv jiný, podstatné však je, že nová větev nevznikne, dokud v ní nevytvoříte alespoň jednu revizi.
6 Pokud byly v PA a PO již nějaké změny oproti původní aktivní větvi, Git se je při načítání nové větve pokusí zachovat.
7 Poznámka: tento příkaz nepřidá do revize žádné dosud neverzované soubory, a pokud jste některý verzovaný soubor přesunuli jinak než příkazem „git mv“, Git už ho nenajde a v revizi skončí jako smazaný.
8 Příkaz „git add“ automaticky ignoruje soubory a adresáře nastavené k ignorování v souboru „.gitignore“.
9 Revizi v každém případě zůstanou rodiče. Neuvedete-li „--reset-author“, zůstane jí i autor a časová známka. Neuvedete-li „--no-edit“, zůstane jí komentář. Vždy se naopak změní obsah a heš. Pozor, ostatní odkazy na nahrazovanou revizi (např. jiná než aktivní větev) budou nadále odkazovat na původní, nezměněnou revizi!
10 Jsou-li v pracovním adresáři změny, tento příkaz se je pokusí zachovat.
11 Výchozí revize je HEAD. Pozor, bez ptaní přepíše změny v pracovním adresáři!
12 Pozor! Cesta/k/souboru nesmí opustit podstrom aktuálního adresáře. Tzn. např. cesta „../x.c“ je neplatná a skončí chybou, a to i v případě, že odkazovaný soubor je verzovaný v daném repozitáři.
13 Poznámka: Jména revizí jsou obvykle trvalá. Pokud se rozhodnete je měnit či mazat, pamatujte, že Git při načítání jmen revizí ze vzdáleného repozitáře nikdy nepřepíše již stažené údaje, takže znovupoužití téhož jména k označení jiné revize povede k tomu, že v repozitářích různých uživatelů bude totéž jméno označovat různé revize, což není dobrý nápad.
14 Příkaz „git merge“ se pokusí do aktivní větve sloučit všechny změny od NSP po uvedenou revizi. Pokud to bude potřeba, vytvoří pro to novou revizi se dvěma rodiči.
15 Příkaz „git revert“ vyžaduje, aby v PO ani PA nebyly žádné změny oproti HEAD. Příkaz vytvoří nové revize s opačným účinkem oproti zadaným revizím.
16 Tento příkaz používejte opatrně. Vyjde od zadané revize a vytvoří zcela novou sérii revizí, ve které revizi po revizi přehrává změny od NSP po aktivní větev. Nakonec nastaví aktivní větev na konec takto vytvořené sekvence revizí, takže se původní revize ztratí, ledaže na ně vedl jiný odkaz (např. jiná větev či jméno revize).
17 Pokud aktivní větev není napojená, příkaz selže s návratovým kódem 128.
18 Vzdálená adresa může být URL nebo místní cesta. Vzniklý repozitář pak bude mít automaticky nastavený vzdálený repozitář „origin“ na uvedenou adresu či cestu.
19 Poznámka: v žádných dvou pracovních adresářích jednoho repozitáře nemůže být současně aktivní tatáž větev; toto opatření platí, aby se zamezilo konfliktům při commitování.
20 Poznámka: PA a PO nemusí být při obnovování změn v přesně stejném stavu jako při odkládání, stačí když při obnovování změn nedojde ke konfliktu.
21 Poznámka: Tento příkaz smaže pouze soubory v aktuálním adresáři a jeho podadresářích; pokud chcete smazat neverzované soubory v celém PA, musíte příkaz spustit v kořeni pracovního adresáře.
22 Vzorek může obsahovat zvláštní znaky „?“, „*“, a konstrukce „[...]“ a „[^...]“.
23 Vhodný počet sekund je např. 300 (5 minut), 86400 (24 hodin), 604800 (týden). Údaje se ukládají pouze v RAM, takže se ztratí restartem systému, možná i odhlášením.
24 Vhodné jsou editory, které otevírají každý soubor v novém procesu, např. „nano“, „vim“, „emacs“, „mousepad“; předpokladem je, že daný editor musíte mít nainstalovaný.
Líbí se vám tento projekt a chcete, aby byl ještě lepší? Můžete mi s tím pomoci. Zmiňte se o něm technicky zdatným přátelům, opravte překlepy a nahlašte nefunkční zaklínadla, aby mohla být opravena; poskytněte mi zpětnou vazbu nebo se zapojte do vývoje nových kapitol. Další informace na GitHubu v dokumentu Jak se zapojit.