Takže, Git už znáš! Teď to začne být trošičku složitější :)
Programátoři občas potřebují pracovat na dvou věcech zároveň. V projektu do práce se objeví se chyba, která musí být opravená ještě dnes, tak programátor/ka opustí, co zrovna dělá, vrátí se k nějaké „stabilní” verzi, opraví chybu a odešle ji zákazníkům. A pak se vrátí k tomu, co dělal/a předtím – jen ještě musí zakomponovat opravu chyby i do verze, na které pracuje dlouhodobě.
Git na to má takzvané větve (angl. branches). Na jedné „větvi” se pracuje, ale je možné se přepnout do jiné (třeba starší) větve, udělat pár změn a pak se zase přepnout do nové větve a pokračovat dál nebo sloučit změny.
Větvení využijeme i při spolupráci více lidí – každý dělá na vlastní větvi a když přijde čas, tak se různé změny sloučí dohromady.
Podívej se, jaké máš větve ve svém repozitáři.
K tomu slouží příkaz git branch
:
$ git branch
* master
Je tam jenom jedna a jmenuje se master
– to je tradičně jméno „hlavní” větve.
K vytvoření nové větve znovu použiješ
git branch
, jen tomu příkazu dáš navíc
jméno nové větve.
Třeba budeš chtít k básničce doplnit jméno autora,
tak větev pojmenuješ doplneni-autora
.
$ git branch doplneni-autora
$ git branch
doplneni-autora
* master
Tenhle příkaz sice udělal novou větev,
ale nepřepnul do ní.
Hvězdička ve výstupu z git branch
ukazuje,
že stále pracuješ v master
.
Na přepnutí budeš potřebovat další příkaz:
$ git checkout doplneni-autora
Switched to branch 'doplneni-autora'
$ git branch
* doplneni-autora
master
Tak. Teď jsi „ve” větvi doplneni-autora
.
Doplň nějaké jméno na začátek souboru basnicka.txt
,
a pomocí git add
a git commit
udělej novou revizi.
Pak koukni na gitk --all
, jak to vypadá:
Aktuální větev – doplneni-autora
– je
zvýrazněná tučně a starší master
je stále
na původní revizi.
Opusťme teď na chvíli práci na doplňování autora.
Vrať se do větve master
a vytvoř z ní
větev doplneni-jmena
.
Pak se na tuhle novou větev přepni.
$ git checkout master
Switched to branch 'master'
$ git branch doplneni-jmena
$ git checkout doplneni-jmena
Switched to branch 'doplneni-jmena'
$ git branch
doplneni-autora
* doplneni-jmena
master
Doplň jméno básně na začátek souboru (tedy na stejné místo,
jako je v druhé větvi název) a pomocí
git add
, git commit
ulož revizi.
Všechno zkontroluj přes gitk --all
.
Takhle nějak se dá postupovat v situaci popsané v úvodu:
opuštění rozpracované verze, přechod na „stabilní”
verzi master
a začátek práce v jiné
části projektu.
Mezi jednotlivými větvemi se dá podle libosti přepínat,
jen je vždycky dobré před přepnutím udělat novou revizi
(git commit
) a pomocí git status
zkontrolovat, jestli je všechno
uložené v Gitu.
Na stejném principu funguje i spolupráce několika lidí
na jednom projektu: je nějaký společný základ
(master
) a každý dělá na vlastní větvi, dokud není se svými změnami spokojený.
A až je některá větev hotová, může se začlenit
zpátky do master
. Podívejme se jak na to.
Nedávalo by smysl historii projektu rozdvojovat, kdyby pak jednotlivé větve nešly zase sloučit dohromady. V Gitu je většinou slučování poměrně jednoduché, ale tento příklad schválně ukazuje nejsložitější variantu, která může nastat.
Přepni se zpátky na master
a použij příkaz git merge
, který
sloučí jinou větev s tou aktuální.
Příkazu musíš dát jméno větve, kterou chceš sloučit.
$ git checkout master
Switched to branch 'master'
$ git merge doplneni-jmena
Updating 1fcd654..5c9bf93
Fast-forward
basnicka.txt | 3 +++
1 file changed, 3 insertions(+)
Sloučeno! Ono „Fast-forward
” znamená, že
vlastně nebylo co slučovat – jen se do větve
master
přidaly nové změny.
Zkontroluj v gitk --all
, jak to vypadá.
A pak zkus sloučit i druhou větev: git merge doplneni-autora
.
Tady to bude složitější: pravděpodobně se stane, že změny nepůjdou
automaticky sloučit a ve výstupu se objeví hláška
merge conflict
(slučovací konflikt):
$ git merge doplneni-autora
Auto-merging basnicka.txt
CONFLICT (content): Merge conflict in basnicka.txt
Automatic merge failed; fix conflicts and then commit the result.
A když ne?
Jestli se konflikt neobjevil, Git změny sloučil sám. Gratuluji! Zbytek téhle sekce bude jen teoretický; vrať se sem, až se ti někdy „podaří“ konflikt udělat.
Když nastane konflikt, git status
ukáže „both modified“ – tedy že byl soubor
změněný v obou slučovaných větvích:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: basnicka.txt
no changes added to commit (use "git add" and/or "git commit -a")
V tom případě se na soubor podívej v editoru: objeví
se v něm obsah z obou konfliktních verzí,
společně se značkami <<<<<<<
, =======
a >>>>>>>
, které upozorňují na
místo kde konflikt nastal.
Značky ukáže i příkaz git diff
, jehož výstup je teď trošku složitější:
$ git diff
diff --cc basnicka.txt
index bc7a2de,88e7ea5..0000000
--- a/basnicka.txt
+++ b/basnicka.txt
@@@ -1,4 -1,4 +1,8 @@@
++<<<<<<< HEAD
+Holka Modrooká
++=======
+ (Lidová)
++>>>>>>> doplneni-autora
Holka modrooká
Nesedávej u potoka
Konflikty a značky, které můžou být nepřehledné, ukazuje Git ze stejného důvodu jako Python chybové hlášky: tedy aby ti co nejvíce pomohl. Git je jen „hloupý“ nástroj a s konfliktem si neporadí sám, ale snaží se ti řešení konfliktu co nejvíc usnadnit.
Proto hlavně nepanikař!
Soubor otevři v editoru a uprav tak, jak by měl vypadat.
Značky jako <<<<<<<
smaž; řádky poskládej tak, jak by měly jít za sebou.
(A pracuješ-li na kódu, spusť testy a ověř, jestli všechno stále funguje.)
Pak soubor ulož a zadej git commit
.
Ať nastal konflikt nebo ne, vytvoří se „slučovací revize“ (angl. merge commit), které – jako každé revizi – můžeš dát popisek. Tentokrát je popisek už předvyplněný; chceš-li nějaký jiný, nahraď ho.
$ git add basnicka.txt
$ git commit
[master 884b30a] Merge branch 'doplneni-autora'
Povedlo se?
Pokud ano, můžeš staré větve vymazat – všechny jejich
změny jsou v master
a nemá na nich cenu
pracovat dál.
$ git branch --delete doplneni-autora
Deleted branch doplneni-autora (was f1cd9be).
$ git branch --delete doplneni-jmena
Deleted branch doplneni-jmena (was 5c9bf93).
$ git branch
* master
Gratuluji, už umíš větvení a slučování!