Jak na git - díl 5.

2 Git, Windows, Linux

Ještě to stále z gitu není vše, pokračování tutoriálu ukáže další možnosti, jako jsou tagy. A protože v gitu je jednoduché něco pokazit, přibudou i nějaké příkazy, co se mohou hodit.

Jak na git - díl 5.

Tento článek patří do seriálu Jak na git. Ostatní články seriálu:


Tagy a jejich využití

Tagy se přiřazují ke commitům a jejich název musí být unikátní. Nelze vytvořit 2 tagy se stejným jménem, nebo jeden tag použít u více commitů. Proto je vhodné volit jasná a neměnná jména tagů jako v1.0.0, ne však release. Zatímco tagem v1.0.0 označíte verzi 1, ta se již nikdy nezmění, případný tag release se asi bude posouvat. To se ale nesmí.

Git obsahuje 2 typy tagů, lightweight a annotated. Lightweight funguje jako obyčejný pointer na nějaký commit, neobsahuje ale žádné informace. Naopak annotated obsahuje všechny informace jako datum, autora, vlastní zprávu apod. Lightweight tagy se nedoporučují používat vůbec, takže to nedělat.

# Vypíše seznam všech tagů
git tag
# Vypíše pouze tagy se jménem, které splňují daný pattern
git tag --list "v1*"
# Vypíše tagy na daném commitu, lze použít i jiné objekty gitu
git tag --points-at b7ef32

# Přidá tag k aktuálnímu commitu
# POZOR -- vynecháním přepínače -a se vytvoří lightweight tag
git tag -a v2.0-beta -m "Releasing v2 beta"
# Přidání zpětně ke staršímu commitu
git tag -a v2.0-beta -m "Releasing v2 beta" dd7216

# Následující operace nelze provést po pushnutí tagů do remote 
# Přesun tagu na jiný commit pomocí --force
git tag -a v1.0 --force
# Odstranění tagu
git tag -d v1.0

# Prohlížení pomocí jména tagu, zobrazí informace o tagu i commitu
git show v1.0

Git a tagy

Tagy - push a pull

Stejně jako větve, se ani tagy nepushnou do remote repozitáře automaticky. Je potřeba jim trochu pomoct. Lze si vybrat, jestli se nahrají všechny tagy nebo jen vybrané.

Pull tagů je o něco jednodušší. Příkaz git pull nebo git fetch stáhne tagy, které se týkají sledovaných větví. Pokud je ale potřeba stáhnout všechny tagy, lze to udělat přepínačem tags u git fetch.

# Nahrání všech tagů
git push --tags
# Nahrání pouze vybraného tagu
git push origin v1.0.0

# Obojí stáhne tagy u sledovaných větví automaticky
git pull
git fetch
# Stáhnutí všech tagů
git fetch --tags

Pokročilejší a nepopsané techniky

Jeden postup, který se při práci s gitem také využívá, se jmenuje rebasing. Sám však o tomto postupu nemám moc potuchy, a i po přečtení několika článků z toho nejsem chytrý. Proto jen odkážu na článek Git Branching - Rebasing.

Jako další, co nebylo zmíněno v minulém článku je udržování jisté synchronizace větví mezi lokálním a vzdáleným repozitářem. Pokud někdo smaže větev v remote repozitáři, v lokálním se to nepromítne. Zase naopak, pokud se smaže v lokálním větev, na vzdáleném stále je. To je správné chování, někdy je ale potřeba toto vyřešit.

# Smazání lokálních větví, které nejsou v remote repozitáři
# Jak bylo zmíněno dříve, tagy se takto nesmažou
git pull --prune
# nebo
git fetch --prune

# Smazání větve/tagu v remote repozitáři
git push origin --delete branchOrTagName

Cherry pick

Jak je popsáno níže, pokazit něco v gitu je někdy až příliš jednoduché. Cherry pick umožní vzít všechny změny provedené commitem a aplikovat je na jinou větev. Toto se hodí, pokud commit je v jiné větvi, a stejné změny je potřeba aplikovat i na aktuální větev. Žádná magie, někomu to ale může dost pomoci.

# Vezme commit a aplikuje na aktuální větev stejné změny
git cherry-pick b7ef32
# Upraví zprávu commitu, který cherry-pick vytvoří
git cherry-pick --edit b7ef32
# Nevytvoří commit, jen aplikuje změny
git cherry-pick --no-commit b7ef32

Kdo říká, že umí s gitem tak kecá

Když se něco posere

Git je opravdu velmi rozšířen, stále vyvíjen a také pekelně složitý. Něco udělat špatně je velmi jednoduché, oprava ale může zabrat hromadu času, až se to nakonec vzdá a stáhne se repozitář znova. Jednou jsem četl větu Kdo říká, že umí s gitem, tak kecá. Něco na tom bude. Ostatně i tato ministránka má něco do sebe Oh shit, git.com.

Zde je seznam pár příkazů, co se můžou hodit. Hodně můžou pomoct příkazy git reset ve druhém díle tutoriálu. Pokazit toho lze ale opravdu hodně.

# Potřebuji přidat soubor do hotového commitu, nebo změnit zprávu
# Přidám všechny soubory jakoby do nového commitu a poté
git commit --amend

# Vytvořil jsem větev, ale nesleduje větev v remote repozitáři
git branch -u origin/branchName
# Pokud se větev lokálně jmenuje jinak
git branch -u origin/branchName localBranchName

# V repozitáři je soubor, který jsem dal později do .gitignore,
# přesto pořád je i v repozitáři a git sleduje jeho změny
git rm --cached fileToIgnoreFromNow.txt
# Pozor, soubor v repozitáři zůstane, ostatním se ale po pull smaže

# Upravil jsem commit, který již byl pushnutý do repozitáře
# Provést jen když nikdo si commity nestáhl a nenavazuje na ně
git push --force

Máte ještě něco ke gitu, o čem byste se chtěli podělit? Stačí napsat komentář.

K tomuto článku již není možné přidávat další komentáře

Komentáře

Pěkná série. Přece jenom bych ten rebase doplnil, není to vůbec špatná věc a může se hodit. Pokud mám změny, o kterých vím že nebudou konfliktní a chci mít pěknou lineární historii bez merge, tak je to naprosto ideální a bezpečná věc.
Další věc kterou sem tam osobně používám (a v článcích dosud nebyla - pokud si dobře pamatuji) je git add -i tzn. interaktivní přidávání. Kdy git postupně prochází soubor/y a u jednotlivých "sekcí" se změnami dá na výběr co se s nimi má stát (přidat, nechat, rozdělit, ...). Pokud chci mít čisté commity tak je to úžasná věc.
A další zájímavá věc o kterém jsem teda jen četl ale nikdy jsme to sice nepoužil, ale určitě se to může hodit - git bisec. Alias binární vyhledávání napříč commity. Primárně je to určená na hledání commitu ve kterém se vyskytla nějaká chyba. Funguje to tak, že určíš commit, o kterém víš, že byl 100% bez chyba. Git bude postupovat binárním půlením tak že ti checkoutne na commit uprostřed mezi aktuálním a tím "správným", ty otestuješ program a řekneš jestli tam ta chyba je nebo ještě ne. Binární půlení podle výsledku pokračuje dál. Jde to i automatizovat. Pokud dokáže napsat skriptík, který ti vrátí danou hodnotu (to si nepamatuji kolik to přesně je) tak git bude půlit, checkoutovat a spouštět tvůj skript a podle výsledku najde ten "zkažený" commit.

Díky za komentář. O interaktivním přidávání hunků bude samostatný článek. Až někdy zjistím více o rebase, tak můžu dopsat.

O git bisec jsem teda neslyšel, ale vypadá to jako brutální funkce. Jak jsem ale psal v článku, git toho umí tolik, že je téměř nemožné znát všechno :D