Tento článek patří do seriálu Jak na git. Ostatní články seriálu:
- Jak na git díl 0 - Co, proč, jak?
- Jak na git - díl 1. - git init, remote, config, clone, add, commit, push
- Jak na git - díl 2. - git status, log, checkout, reset
- Jak na git - díl 3. - git revert, stash, diff, clean
- Jak na git - díl 4. - git pull, git fetch, git branch, git merge
- Jak na git - díl 5. - git tag, git cherry-pick a opravy rozbitého gitu
- Jak na git - díl 6. - git rebase a interaktivní rebase
- Git - přidávání částí souborů do commitu
- Git - tutoriály a návody
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
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
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