Linux: Kniha kouzel, vanilková příchuť 1.17 (27. února 2022)
Veškerá moc příkazové řádky/příkazového řádku přehledně, pro začátečníky i pokročilé

7. Git

Řada 1.x vanilkové příchuti Linuxu: Knihy kouzel je od 1. října 2020 do 1. března 2023 ve stavu dlouhodobé pasivní údržby; nahlášené chyby budou opravovány, ale aktivní vývoj se již věnuje novější vývojové řadě určené pro novější verze operačního systému a programů. Pokud nejste vázáni na starší verze programů, doporučuji vyhledat novou verzi z aktivně vyvíjené vývojové řady.
program správa verzí

1. Úvod

Git je systém správy verzí. Umožňuje vám zachytit přesný stav souborů v určitém adresáři a jeho podadresářích. Každý takto zachycený stav se opatří datem, časem a popisem a později se k němu můžete vrátit, nebo ho exportovat do samostatného adresáře. Kromě toho umožňuje git synchronizaci a slučování změn v jinak oddělených kopiích daného adresáře a perfektní evidenci změn v textových souborech.

Tato verze kapitoly nepokrývá dostatečně řešení konfliktů při slučování větví a příkaz „git stash“.

2. Definice

2/1 Označení revize

Každá revize je jednoznačně identifikována pomocí své SHA-1 heše. Kromě této úplné heše můžeme pojmenovat revizi těmito způsoby:

3. Zaklínadla

3/1 Práce s repozitáři

vytvořit nový repozitář v aktuálním adresáři (normální/bare)#1
git init [&& git checkout -b název_výchozí_větve]
git init --bare
vytvořit lokální repozitář ze vzdáleného#2
git clone vzdálená-adresa [místní-adresář]
získat do samostatného nového adresáře konkrétní revizi#3 (1)
git worktree add --detach nový/adresář revize &&rm nový/adresář/.git && git worktree prune
konverze bare repozitáře na normální#4
git -C repozitář config core.bare false
mv repozitář repozitář-git
mkdir repozitář
mv repozitář-git repozitář/.git
git -C repozitář reset --hard
konverze normálního repozitáře na bare repoziťář#5
mv repozitář/.git repozitář-git
rm -R repozitář
mv repozitář-git repozitář
git -C repozitář config core.bare true

3/2 Mezi pracovním adresářem, indexem a lokálním repozitářem

načíst zadanou revizi do pracovního adresáře i indexu (jen načíst/načíst a vytvořit z ní ní novou větev)#1 (2)
git checkout revize
git checkout -b nová-větev [revize]
přenést do indexu změny v pracovním adresáři (všech souborů/jen již verzovaných)#2 (3)
git add [-A] [--] soubor-nebo-adresář
git add -u [-A] [--] [soubor-nebo-adresář]
operace commit (vytvořit z indexu novou revizi a nastavit na ni aktuální větev)#3
git commit [-m komentář] [-a] [--allow-empty] [--amend] [-S] [--reset-author]
nahradit poslední commitnutou revizi novým commitem se zachováním původního autora, předků, komentáře a časové známky#4 (4)
git commit --amend --no-edit
načíst konkrétní soubory z revize v repozitáři do pracovního adresáře a indexu#5 (5)
git checkout [revize] [--] soubor-nebo-adresář
načíst HEAD do indexu/do indexu a pracovního adresáře (zrušit všechny změny)#6
git reset
git reset --hard
načíst konkrétní soubory z revize v repozitáři do indexu#7 (6)
git reset [revize] [--] soubor-nebo-adresář
načíst do pracovního adresáře i indexu revizi, která byla nejnovější k určitému datu/před 14 dny#8
git checkout $(git rev-list -n 1 --first-parent "--until=datum-YYYY-MM-DD HH:mm:ss" HEAD)
git checkout $(git rev-list -n 1 --first-parent "--until=$(date -d "14 days ago" "+%F %T")" HEAD)
smazat soubor z pracovního adresáře i indexu/jen z indexu#9
git rm [-f] [-r] [[--] soubor-či-adresář]
git rm --cached [-f] [-r] [[--] soubor-či-adresář]
přesunout či přejmenovat soubor/přesunout soubory v pracovním adresáři i indexu#10
git mv původní-cesta nová-cesta
git mv zdroj cílový-adresář
vypsat na standardní výstup konkrétní soubor z konkrétní revize#11

3/3 Práce se vzdáleným repozitářem (origin)

stáhnout všechny novinky a aktualizovat právě načtenou větev#1 (7)
git pull
odeslat změny v aktuální větvi z lokálního repozitáře do vzdáleného (jednorázově/nastavit/větev už je nastavená)#2
git push origin větev
git push -u origin větev
git push
vytvořit novou větev z HEAD a odeslat ji do vzdáleného repozitáře#3
git checkout -b nová-větev
git push -u origin nová-větev
odeslat zadané větve (existující větve ve vzdáleném repozitáři budou přepsány)#4 (8)
git push [-u] origin větev
odeslat zadané tagy#5
git push origin tag
smazat zadanou větev nebo tag ze vzdáleného repozitáře#6
git push :větev-nebo-tag [:další-větev-nebo-tag]
stáhnout všechny novinky ze vzdáleného repozitáře#7
git fetch

3/4 Jednoduchá práce s větvemi

vytvořit novou větev z HEAD a přepnout se na ni (nezmění pracovní adresář ani index)#1
git checkout -b nová-větev
vytvořit novou větev a přiřadit jí HEAD/určitou revizi (lze použít k duplikaci větve)#2
git branch nová-větev
git branch nová-větev revize
smazat větev (jen sloučenou/kteroukoliv)#3 (9)
git branch -d větev
git branch -D větev
přejmenovat větev#4
git branch -m starý-název nový-název
ručně přiřadit aktuální větvi určitou revizi (i nesouvisející)#5
git reset --soft revize
vytvořit novou odpojenou větev (orphan branch)(z určité revize/zcela prázdnou)#6
git checkout --orphan [revize]
git checkout --orphan && git rm -rf .

3/5 Jednoduchá práce s tagy

vytvořit nový tag (normální/anotovaný)#1
git tag název-tagu [revize]
git tag -a -m komentář [revize]
vypsat seznam tagů (všech/odpovídajících vzorku)#2
git tag
git tag -l "vzorek"
smazat tag#3 (10)
git tag -d název-tagu

3/6 Analýza stavu

vypsat „pro člověka“ běžné informace (aktuální větev a změněné soubory v indexu a pracovním adresáři)#1
git status [soubor-či-adresář]
vypsat změny v pracovním adresáři oproti HEAD/v pracovním adresáři oproti indexu/v indexu oproti HEAD#2
git diff HEAD [-- soubor-nebo-adresář]
git diff [-- soubor-nebo-adresář]
git diff --cached [-- soubor-nebo-adresář]
vypsat rozdíly mezi dvěma revizemi#3
git diff revize1 revize2 [-- soubor-nebo-adresář]
vypsat „pro člověka“ zpětnou historii předků aktuální revize (až po kořen/jen po první revizi dosažitelnou z „omezující-revize“)#4
git log [--pretty=formát] [-n maximální-počet-revizí] [revize]
git log [--pretty=formát] [-n maximální-počet-revizí] omezující-revize..revize
vypsat „pro člověka“ zpětnou historii revizí, u kterých došlo ke změně v některém z uvedených souborů#5
git log [--pretty=formát] [-n maximální-počet-revizí] [revize] -- soubor-nebo-adresář
vypsat podrobné informace o revizi#6
git show revize
vypsat (pro skript) seznam tvořený revizí a všemi jejími předky#7
git rev-list revize
vypsat úplnou heš dané revize#8
git rev-list -n 1 revize

3/7 Sekundární pracovní adresáře

vytvořit#1 (11)
git worktree add [--detach] [-b nová-větev] /nový/adresář revize
vypsat seznam#2
git worktree list [--porcelain]
smazat#3
git worktree remove /sekundární/pracovní/adresář
۵smazat všechny nedostupné sekundární pracovní adresáře#4
git worktree prune
přesunout#5
git worktree move /sekundární/pracovní/adresář /nové/umístění
zamknout/odemknout (zamknutý adresář se nesmaže příkazem „prune“)#6
git worktree lock [--reason důvod] /sekundární/pracovní/adresář
git worktree unlock /sekundární/pracovní/adresář

3/8 Slučování větví a řešení konfliktů

sloučit rozdíly mezi HEAD a uvedenou revizí do aktuální větve provedením commitu#1 (12)
git merge revize

3/9 Práce se změnami z revizí (pokročilá)

odvolat změny z určitých revizí/z určitého rozsahu revizí a odvolání commitnout#1 (13)
git revert [--no-edit] [-n] revize
git revert [--no-edit] [-n] starší-revize..novější-revize
přenést změny z uvedených revizí do aktuální větve (seznam revizí uvést v příkazu/načíst)#2
git cherry-pick [-x] [-n] revize
příkaz generující seznam revizí | git cherry-pick --stdin [-x] [-n]
zařadit změny provedené v jiné větvi před změny provedené v této větvi#3 (14)
git rebase revize-jiná-větev

3/10 Konfigurace repozitáře (obecně)

vypsat současnou hodnotu určitého klíče#1
git config [--global] --get klíč
nastavit hodnotu určitého klíče#2
git config [--global] klíč "nová hodnota"
vypsat celou konfiguraci (lokální/globální/globální a pod ní lokální)#3
git config --local -l
git config --global -l
git config -l
vypsat platné konfigurační dvojice klíč=hodnota#4
git config -l | tac | awk -F = '/=/ && !($1 in A) {A[$1] = 1; print $0;}' | LC_ALL=C sort
najít seznam podporovaných konfiguračních klíčů#5
git config --help

3/11 Konfigurace gitu či repozitáře (konkrétně)

v logu zobrazovat datum ve formátu YYYY-MM-DD HH:MM:SS +ZZZZ (např. „1970-12-31 23:59:59 +0700“)#1
git config [--global] log.date iso
vypisovat ne-ASCII znaky v názvech souborů tak, jak jsou#2
git config [--global] core.quotePath false
po přihlášení (např. na GitHub) si nějakou dobu pamatovat přihlašovací údaje#3 (15)
git config [--global] credential.helper "cache --timeout=počet-sekund"
nastavit editor, který má být vyvolán pro editaci komentářů k revizím#4 (16)
git config [--global] core.editor příkaz

4. Zaklínadla (.gitignore)

komentář#1
# [text do konce řádky]
ignorovat soubory a adresáře vyhovující vzorku (může obsahovat znaky ? a * ve stejném významu jako v bashi)#2
vzorek
ignorovat pouze adresáře vyhovující vzorku#3
vzorek/

5. Parametry příkazů

git [globální parametry] příkaz [parametry příkazu]
git [globální parametry] commit [parametry]
git [globální parametry] add [parametry]

6. Instalace na Ubuntu

sudo apt-get install git
git config --global user.name "vaše celé jméno"
git config --global user.email "váš e-mail"

Celé jméno a e-mail se používají k označení autorství revizí. Musíte je zadat, jinak git nebude fungovat, ale nemusí být pochopitelně pravdivé. Pro konkrétní repozitář můžete nastavit jiné hodnoty použitím stejných konfiguračních příkazů bez parametru --global.

7. Ukázka

Příprava ukázkového adresáře a souborů#1
mkdir Projekt && cd Projekt
printf %s\\n "#!""/bin/bash" "cat text" > skript
chmod 755 skript
printf %s\\n "Toto je textový soubor" > text
Tělo příkladu#2
git init
git add skript text
git commit -m "První verze"
printf %s\\n "Druhá řádka" >> text
git status
git commit -a -m "Přidána druhá řádka"
git log
Druhá část příkladu#3
git checkout -b nova-vetev HEAD~1
printf %s\\n "Jiný druhý řádek" >> text
git commit -a -m "Alternativní verze"
git diff master nova-vetev

8. Tipy a zkušenosti

9. Další zdroje informací

git --help
git příkaz-gitu --help

Další dobrou možností je oficiální online referenční příručka (viz sekci „Odkazy“). 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“.

10. Odkazy

1 Poznámka: nový adresář musí ležet mimo stávající pracovní adresář. Můžete jej zadat jak relativní, tak i absolutní cestou.
2 Jsou-li v pracovním adresáři změny, tento příkaz se je pokusí zachovat.
3 Normálně „git add“ přenese smazání souboru jen tehdy, je-li daný soubor výslovně jmenován na příkazovém řádku. S parametrem „-A“ přenese všechna smazání.
4 Pozn.: heš commitu se v tomto případě změní, protože revize je neměnná, takže jediný způsob, jak ji upravit, je vytvořit novou revizi a nahradit s ní tu původní.
5 Výchozí revize je HEAD. Pozor, bez ptaní přepíše změny v pracovním adresáři!
6 Výchozí revize je HEAD.
7 Pokud ve vzdáleném repozitáři nastaly změny i v jiných větvích, než té, která je právě načtená do pracovního adresáře, příkaz „git pull“ tyto jiné větve neaktualizuje!
8 Poznámka: Příkaz „git push“ selže, pokud vzdálený repozitář není bare.
9 Pozor, při smazání nesloučené větve můžete přijít o commitnuté revize, které přestanou být po smazání dané větve dostupné!
10 Mazání a znovuvytvoření zcela lokálního tagu, který nemá obdobu ve vzdáleném repozitáři, je bezpečné. Všechny ostatní případy mohou mít nepříjemné nečekané důsledky.
11 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í.
12 Dojde-li při slučování ke konfliktu, můžeme je zrušit příkazem „git merge --abort“.
13 Příkaz „git revert“ vyžaduje, aby v indexu ani pracovním adresáři nebyly žádné změny oproti HEAD.
14 Pozor! Protože revize jsou neměnné včetně odkazů na své předky, tento příkaz vytvoří zcela novou historii větve, a změní tak heše všech jejích revizí.
15 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.
16 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ý.
MarkdownVimRegulární výrazy