Posledních pár měsíců používám větve v gitu víc intenzivně a rozhodl jsem se podělit o zkušenosti s touto funkcí gitu, o to, jak větve používám a také o to, co se mi nepovedlo – aby se to nemuselo stát i vám.

Určitě během čtení narazíte na něco, co třeba používáte jinak – dejte mi vědět v komentářích, rád se dozvím něco nového!

Proč vlastně používat větve?

Jednoduše řečeno – protože je to pohodlné. Větve umožňují pracovat na více věcech zároveň, aniž by se tyto věci prolínaly. Můžu tak pracovat na nové feature a zároveň průběžně odstraňovat bugy, které se objeví na produkci, aniž bych míchal kód dohromady.

Základní větev - master

Jako základní větev používám master. Tuto větev synchronizuji pomocí příkazu git pull s centrálním repozitářem a z této větve vytvářím další samostatné větve. Zároveň tuto větev udržuji čistou a vůbec v ní neprogramuji. To je hodně důležité – podařilo se mi vyvíjet delší dobu novou feature v masteru a pro rychlou opravu malého bugu jsem vytvořil novou větev, kterou jsem vytvořil z masteru. Jak správně tušíte, tato nová větev obsahovala nedokončenou feature a zároveň opravu bugu. Pro nasazení na produkci tedy nebyla úplně vhodná.

Vytvoření nové větve

Nové větve je tedy ideální vytvářet pokud jsme aktuálně ve větvi master. To zjistíme například pomocí příkazu git status.

Řekněme, že chceme vytvořit větev s názvem feature. Zadáme tedy příkaz git branch feature. Obecně se pro vytvoření nové větve používá git branch <název-větve>.

Pro kontrolu, že se větev opravdu vytvořila, zadáme git branch, který vypíše seznam větví.

A je to tam! Nyní máme vytvořenou větev feature. Hvězdičkou je na předchozím screenu označena větev, ve které se právě nacházíme – a to je master. Abychom mohli začít pracovat na nové funkcionalitě ve větvi feature, je potřeba zadat git checkout feature, který nás přepne do větve feature. Obecně se pro přepnutí do jiné větve používá příkaz git checkout <název-větve>.

Pokud bychom chtěli kroky vytvoření větve a přepnutí spojit do jednoho, můžeme použít příkaz git checkout -b <název-větve>.

Nyní jsme ve větvi feature a můžeme si v klidu vyvíjet, co je potřeba. Řekněme, že třeba pracujeme na feature.php

Spojení větví dohromady

Nyní přijde požadavek na rychlé odstranění chyby. Mezitím jsme pokročili s vývojem feature.php, který jsme commitli a nemáme tedy žádné změněné, nové nebo smazané soubory (to je důležité, jinak se nepůjde přepnout do jiné větve).

Přepneme se tedy do větve master a z ní vytvoříme novou větev bug.

Bug odstraníme přidáním soubor bug.php (takový malý zázrak :-D). Změny commitneme. Nyní potřebujeme dostat změny z větve bug do větve master, ze které pushneme do centrálního repozitáře. (pozn.: zkuste se nyní pro kontrolu přepnout do větve feature – soubor bug.php zde neuvidíte, protože se nachází pouze ve větvi bug).

Přepneme se do větve master pomocí git checkout master.

Abychom do větve master dostaly nové změny z větve bug, zadáme příkaz git rebase bug. Pozn.: podívejte se do repozitáře a uvidíte soubor bug.php.

Podařilo se nám tedy ve větvi bug odstranit chybu a dostat tento kód do větve master. Z větve master můžeme provést push do centrálního repozitáře.

Smazání větve

Protože již nebudeme větev bug na nic potřebovat, můžeme ji smazat pomocí git branch -d bug. Obecně se příkaz pro smazání větve používá ve tvaru git branch -d <název-větve>.

Nyní se můžeme v klidu pomocí git checkout feature vrátit do větve feature a pracovat na původním úkolu.

Udržování větví v aktuálním stavu

Abychom nepracovali na kódu, který již někdo změnil a který tedy není aktuální, je dobré pravidelně kód aktualizovat nehledě na to, v jaké větvi se nacházíme. Do jakékoli větve můžeme stáhnout aktuální verzi kódu pomocí git pull origin master, kde origin je název vašeho remote repozitáře.

Naopak není možné provést push z libovolné větve do větve master – což dává smysl. Pokud jsem ve větvi feature, většinou nechci provést push do větve master.

Složitější přepínání větví

Přepínání větví jsem ilustroval na ideálním případu, ve kterém mám ve chvíli, kdy se chci přepnout do jiné větve, všechny poslední změny commitlé. Většinou se mi ale stává, že se potřebuju přepnout na jinou větev ve chvíli, kdy mám něco rozpracované, ale ne ukončené.

Pro tyto případy používám malý workaround, kdy si všechny změny commitnu s nějakou hláškou, ze které poznám, že změny ještě nejsou finální, typicky uncommit later.

Poté se přepnu do jiné větve a udělám, co potřebuji.

Když se poté vrátím na původní větev a zobrazím si poslední změny pomocí git log, poznám podle své hlášky, že se mám vrátít k rozpracovanému.

Příkazem git reset HEAD~1 odeberu poslední commit, takže nicneříkající hlášku uncommit later neuvidí nikdo jiný. Zároveň se nezmění stav souborů – poslední změny, které jsem provedl před tím, než jsem se potřeboval přepnout do jiné větve, zůstaly zachovány.

Pokud nechcete používat tento workaround, podívejte se na příkaz git stash – měl by dělat přesně to samé. Já se na něj podívám taky a naučím se ho používat do příště :-).

Zdroje

Především http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging a http://stackoverflow.com/