brenčTakébranche, vývojová větev, feature branchZákladní

Definice

Branch je pojmenovaný ukazatel na konkrétní commit ve verzovacím systému, který umožňuje vyvíjet změny odděleně od hlavní linie kódu. Ve výchozím nastavení se posouvá dopředu s každým novým commitem. Díky větvím může na jednom repozitáři pracovat víc lidí současně, aniž by si navzájem rozbíjeli rozpracovanou práci.

Kategorie: Softwarový vývojAktualizováno

Nezaměňujte: V programování označuje branch také podmíněný skok v instrukčním toku procesoru (branch prediction), zatímco ve verzovacích systémech jde o vývojovou větev kódu.

Co branch ve skutečnosti je

Branch v Gitu není kopie souborů ani samostatný adresář. Branch je soubor o velikosti několika desítek bajtů, který obsahuje hash jednoho commitu. Protože každý commit zná svého rodiče, stačí tenhle jediný ukazatel k tomu, aby se dala zrekonstruovat celá historie vedoucí k němu. Právě proto je vytvoření větve v Gitu okamžité: nekopíruje se nic, jen se zapíše nový odkaz.

Ukazatel HEAD říká, na které větvi právě stojíte. Když uděláte commit, Git vytvoří nový objekt a posune aktuální větev na něj. Starší systémy jako Subversion řešily větvení kopírováním celého stromu na serveru, což bylo pomalé a odrazovalo od častého větvení.

Proč se větve v praxi zakládají

Typický důvod je izolace rozpracované práce. Nová funkce, oprava chyby nebo experiment žijí ve vlastní větvi, dokud nejsou hotové. Hlavní větev (dnes obvykle main, dříve master) tak zůstává v nasaditelném stavu a CI pipeline nad ní běží zeleně.

Druhý důvod je code review. Pull request neboli merge request je technicky návrh sloučit jednu větev do druhé, takže větev funguje jako jednotka, o které se diskutuje a která se schvaluje.

Merge versus rebase

Sloučení větve zpět má dvě běžné cesty. git merge vytvoří spojovací commit se dvěma rodiči a zachová skutečný tvar historie. git rebase naopak přepíše commity tak, jako by vznikly až nad aktuální špičkou cílové větve, a historie zůstane lineární. Rebase se nikdy nedělá na větvi, kterou už někdo jiný stáhl: přepsané hashe rozbijí kolegům lokální kopii.

Lokální a vzdálené větve

Lokální větev existuje jen ve vašem klonu. Vzdálená sledovací větev typu origin/main je záznam o tom, kde větev stála na serveru při posledním fetch. Tyhle dvě věci se často pletou: git fetch aktualizuje sledovací větev, ale vaši lokální větev nechá být, dokud nesloučíte.

Kolik větví je zdravé

Dlouho žijící větve jsou nejčastější zdroj bolestivých konfliktů. Čím déle se větev vyvíjí odděleně, tím víc se rozchází s hlavní linií a tím dráž se slučuje. Modely jako trunk-based development to řeší tím, že větve žijí hodiny nebo jeden den a nedokončené funkce se schovávají za feature flag. Naopak Git Flow s dlouhými větvemi develop a release dává smysl hlavně tam, kde se dodává v jasně oddělených verzích, třeba u desktopového nebo krabicového softwaru.

Po sloučení nemá smysl větev držet. Smazaná větev nezničí commity, jen odstraní ukazatel; historie zůstává dosažitelná přes cílovou větev.

Příklady z praxe

  1. Založení větve pro opravu chyby

    Vývojář dostane ticket o špatně počítaném DPH v košíku. Vytvoří větev odvozenou od aktuálního main, opraví výpočet, pushne ji a otevře pull request. Main mezitím zůstává nasaditelný, protože oprava do něj vstoupí až po schválení.

    git switch -c fix/dph-vypocet main
    # úpravy kódu
    git commit -am "Oprava zaokrouhlení DPH v košíku"
    git push -u origin fix/dph-vypocet
  2. Rozejitá větev a řešení konfliktu

    Větev s redesignem formuláře žije tři týdny a mezitím se v main přepsala validace. Při slučování Git ohlásí konflikt ve stejném souboru. Vývojář si stáhne aktuální main, přeloží na něj svou práci a konflikty vyřeší po jednotlivých commitech místo v jednom velkém balíku.

    git fetch origin
    git rebase origin/main
    # Git zastaví na konfliktním commitu
    git add src/form/validate.ts
    git rebase --continue

Časté omyly

MýtusKdyž založím větev, Git si někam zkopíruje všechny soubory projektu.
Ve skutečnostiVytvoření větve zapíše jen jeden malý soubor s hashem commitu. Pracovní adresář se přepíše až při přepnutí a i tehdy se používají už existující objekty v repozitáři.
MýtusSmazáním větve přijdu o svoje commity.
Ve skutečnostiSmazání větve odstraní pouze ukazatel. Pokud byly commity předtím sloučeny jinam, zůstávají dostupné; i nesloučené commity lze nějakou dobu dohledat přes reflog, než je odklidí garbage collector.
MýtusRebase je vždycky lepší než merge, protože historie vypadá čistě.
Ve skutečnostiRebase přepisuje hashe commitů, takže na sdílené větvi rozbije práci ostatním. Lineární historie navíc zakryje informaci o tom, kdy se práce reálně integrovala.

Časté dotazy

Jak pojmenovávat větve v týmu?
Větve se obvykle pojmenovávají prefixem podle typu práce a identifikátorem úkolu, například feat/1234-export-faktur nebo fix/login-timeout. Konzistentní prefix umožňuje filtrovat větve, automaticky spouštět různé CI kroky a snadno dohledat souvislost s ticketem. Vyhněte se mezerám, diakritice a znakům, které Git nepovolí, a délku držte krátkou, protože název se objevuje v pull requestech i v logu. Mnoho týmů si pravidlo vynucuje kontrolou na serveru, aby se do repozitáře nedostaly větve typu test2 nebo oprava-final.
Kdy stačí pracovat přímo v main bez větví?
Práce přímo v main dává smysl u sólo projektů, prototypů a repozitářů bez code review, kde nikdo jiný nečeká na stabilní stav kódu. Jakmile na projektu pracuje víc lidí, běží nad ním nasazování nebo se vyžaduje schvalování změn, přímé commity do main obcházejí kontrolu a snadno rozbijí produkci. Kompromisem je trunk-based development: krátké větve žijící hodiny, které se slučují několikrát denně a nedokončené části se skrývají za feature flag.
Co dělat s větví, kterou už nikdo nesloučí?
Opuštěnou větev je nejlepší smazat, ale nejdřív ověřit, jestli obsahuje commity, které nejsou nikde jinde. Příkaz git branch --no-merged main ukáže větve s neintegrovanou prací. Pokud v ní je něco cenného, dá se to vytáhnout jako cherry-pick jednotlivých commitů nebo označit tagem, který na commit ukazuje trvale. Ponechávat desítky mrtvých větví na serveru komplikuje orientaci, zpomaluje nástroje a vytváří dojem, že se na věci ještě pracuje.
Proč vzniká konflikt při slučování větví?
Konflikt vzniká tehdy, když dvě větve změnily stejné řádky stejného souboru a Git nemá jak rozhodnout, která verze platí. Automaticky zvládne změny v různých místech souboru nebo v různých souborech, ale ne dvojí přepis téhož místa. Riziko roste s délkou života větve a s velkými refaktoringy. Nejúčinnější prevence je slučovat často, držet změny malé a před dokončením větve do ní pravidelně stahovat aktuální stav hlavní linie.

Zdroje

  1. Git - Book(otevře se v novém okně)Git
  2. git-branch Documentation(otevře se v novém okně)Git
  3. git-rebase Documentation(otevře se v novém okně)Git
  4. Branching (version control)(otevře se v novém okně)Wikipedia

Související pojmy

Potřebujete to vyřešit v praxi?

Poradíme, jak na to ve vašem projektu

Vysvětlit pojem je jedna věc, navrhnout kolem něj funkční řešení druhá. Ozvěte se a probereme, co dává smysl u vás.