Devel.cz Lupa Měšec Podnikatel Root Zdroják.cz DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Druhý důvod proč zvolit Git: Snadné vytváření a slučování větví

V minulém článku jsme ukázali, že Git je nástroj pro správu verzí, který je zároveň velmi jednoduchý i velmi flexibilní. Především nám však nevnucuje pečlivé plánování pracovních postupů a neříká „to jsi nejdřív měl…“ Dnes se podíváme na to, zdali to platí i při práci s větvemi (branch) a jejich slučováním (merge).

Tweetni to Twitter Jaggni to! Jagg Del.icio.us Delicious

Minule jsme si ukázali, že Git se velmi, velmi snaží být užitečným pomocníkem při práci, a ne tupým nebo přechytralým nástrojem na „ukládání historie a sdílení dat“. A neopouští nás ani při základní součásti práce s verzovacím systémem: při vytváření větví a jejich slučování. Už jen při vyslovení slůvka merge může snadno mnoha uživatelům některých jiných verzovacích systémů naskakovat husí kůže a myšlenky na dovolenou.

Efektivní práce s větvemi tvoří naopak samotné srdce Gitu; koncept paralelního vývoje (kód žije v oddělených světech, které se někdy protínají a někdy ne) je pro něj stejně důležitý jako koncept „verzování“. Jak říká Jeff Atwood, pokud používáte verzovací systém a nepoužíváte paralelní vývoj ve větvích, využíváte jeho schopnosti velmi omezeně.

Git vysloveně ponouká k tomu, pracovat paralelně v oddělených větvích, a snaží se takový způsob práce co nejvíce usnadňovat. Mohu tak na rozsáhlejších změnách pracovat několik dní (nebo třeba týdnů), a mohu si přitom vybrat, zda chci tuto práci sdílet s ostatními, či nikoliv. Pomocí příkazugit fetch agit merge (nebo v tomto případě spíše git rebase , ale nepředbíhejme) mohu do takové paralelní větve průběžně začleňovat aktualizace z ostatních sdílených větví.

Paralelní větve si mohu vytvořit pro uvedené rozsáhlejší změny (často nazývané topic branches) nebo pro nezávazné zkoušení divokých nápadů (tzv. experiment branches), ale též pro oddělení různých verzí a vydání (větve deploy či v1, apod.) v rámci release management. Jednotliví členové týmu mohou také publikovat práci do „svých“ větví (tzv. developer branches). Způsobů využití větví je nepřeberně — důležité je, aby bylo možné mezi větvemi snadno a rychle přecházet a sdílet mezi nimi změny. Git je přeborníkem v obou ohledech.

GIT Branches workflow

V Gitu můžeme, tak jako v ostatních systémech, vytvořit branch a přepnout se do ní předtím, než v ní začneme pracovat:

$ git branch new-branch           # Vytvor vetev 'new-branch' ...
$ git checkout new-branch         # ... a prepni se do ni
$ git checkout -b another-branch  # Nebo vyuzij zkracenou variantu v jednom kroku 

Můžeme ale branch vytvořit kdykoliv v průběhu práce, a rozpracovaný obsah si tak do ní „přetáhnout“. K takové situaci dochází typicky tehdy, kdy si (ve volné parafrázi Linuse Torvaldse) řeknu: „Ouha!, tahle věc mi zabere daleko více času a je daleko složitější, než jsem si původně myslel, a raději bych commitoval do zvláštní větve a ne naostro do větve hlavní“. (Jak již víme, Git neříká „to jsi nejdřív měl…“)

Zjednodušená workflow při práci v Gitu může tedy vypadat například takto:

# Vytvorime si branch "msie_fix" jako "sandbox" pro praci
$ git checkout -b msie_fix
# ... Pracujeme, testujeme, klejeme

# Pripravime zmeny v souborech ke commitu
$ git add public/css/msie6.css

# Ulozime revizi do repositare
$ git commit -m "Oprava problemu pri prihlasovani z MSIE6"

# Zaclenime praci z topic branche do master
$ git checkout master
$ git merge msie_fix

# A odeslene do vzdaleneho repositare
$ git push origin master 

Proč „zjednodušená“? Protože nebere v úvahu to, že ve vzdáleném repositáři mohly přibýt změny od někoho jiného, pracujeme-li v týmu. V takovém případě nám Git ohlásí, že nemůže příkaz provést:

! [rejected] master -> master (non-fast forward)
error: failed to push some refs to ... 

Nejjednodušším řešením je stáhnout a začlenit si změny ze vzdáleného repositáře do našeho (v jednom kroku):

$ git pull origin master
Merge made by recursive. 

V případě vývoje v týmu taková „zjednodušená“ (byť zhusta používaná) workflow vede k nepřehledné historii, ohlášené slovy Merge made by recursive. O kousek níže v článku si vysvětlíme, jak se tomu vyhnout.

Důležité je, že hlavní větev (master) máme „čistou“ a změny v obsahu provádíme izolovaně ve větvi jiné. Publikovat je můžeme samostatně i v rozpracovaném stavu (třeba proto, aby je zkontrolovali kolegové) nebo je můžeme začlenit do hlavní větve, jakmile jsou hotové.

Znovu a lépe

To, že Git neříká „to jsi nejdřív měl…“ ale v kontextu větví a slučování znamená ještě víc. V Gitu probíhá všechna práce lokálně, dokud ji výslovně neodešlu (git push ) do sdíleného repositáře. Mohu tedy kód „rozvětvit“ dokonce i v případě, že jsem uložil revizi v hlavní větvi (master) a teprve poté zjistil, „Ouha!, tohle je daleko složitější, než jsem si myslel…“. Uvažujme tuto fiktivní situaci ve větvi master

(časově poslední změny nahoře):

$ git log --oneline

fb00250 Přidána možnost přihlášení přes OpenID
75bc299 [FIX] Oprava přihlašovacího formuláře (validace délky hesla)
c56fb7b Přidán přihlašovací formulář
# ...   (starsi revize) 

Revize c56fb7b je již ve sdíleném repositáři a nasazena v aplikaci na serveru. Revizi 75bc299, která opravuje chybu, jsme právě přidali přímo do větve master a zároveň zpracovali podporu pro OpenID („triviální!“), kterou jsme uložili odděleně, v revizi fb00250. Červíček ale hlodal, a po chvilce manuálního zkoušení se ukázalo, tak jako často, že to není tak úplně triviální, a „bude to chtít více času“. Ale nefunkční funkcionalitu jsme již do hlavní větve uložili ( fb00250). Při práci v centralizovaném verzovacím systému právě nastává fáze zrychleného tepu, frenetického opravování a několika commitů obsahujících slovo „oprava“.

Při práci v Gitu nemáme problém se z takové šlamastyky vymotat. Řekněme, že chceme do sdíleného repositáře poslat opravu v 75bc299  a polo-funkční fb00250 si „přetáhnout“ do soukromé branche, kde se budeme OpenID věnovat v klidu dále. Celý postup by pak vypadal asi takto:

$ git branch openid fb00250   # Vytvorime novou branch "openid" odvozenou z commitu "fb00250"
$ git reset 75bc299 --hard    # Vratime branch "master" na predchozi commit "75bc299 [FIX] ..."
$ git push origin master      # Odesleme FIX do sdileneho repositare

$ git checkout openid         # Prepneme se do branche "openid", kde muzeme pracovat dale 

Když máme konečně OpenID funkcionalitu hotovou, chceme ji začlenit do „master“ branche a poslat do sdíleného repositáře. Uvažujme situaci, kdy ve sdíleném repositáři mezitím přibyly změny od někoho jiného ( 671aada):

$ git fetch                                  # Stahni informaci o novinkach ze serveru
$ git log --oneline master..origin/master    # Jake revize pribyly na serveru?
671aada Zmena na 'serveru' 

Chcete-li se naučit efektivně využívat všechny možnosti Gitu, objednejte si od autora článku školení, nebo si rezervujte místo v kurzech na www.git-fu.cz.

Nyní máme dvě fundamentálně odlišné možnosti, jak pokračovat:git merge a git rebase . Zjednodušeně řečeno, první spojuje paralelní větve s tím, že ukládá informace o samotném sloučení, druhá historii „přeskládává“ a linearizuje; vysvětlení by zabralo celý článek, proto jen odkážeme na velmi hezké vysvětlení s obrázky. Mezi gitstery se vede spor, zda je důležitější zcela přesný záznam historie v repositáři, nebo přehledná a čitelná historie. Autor článku upřednostňuje druhou variantu, připomeňme však, že v Gitu lze velmi snadno při chytré práci s větvemi zachovat obojí. Další informace hledejte v rámečku „Philosophy of Altering History“ v knize Jona Loeligera Version Control with Git.

V našem případě se rozhodneme pro možnost druhou a využijeme přepínače --rebase pro příkaz git pull , kterým si změny ze sdíleného repositáře ( 671aada) „přeskládáme“ a začleníme před naše vlastní změny:

$ git checkout master         # Prepneme se do branche "master",
$ git merge openid            # ... a zaclenime zmeny z branche "openid" do "master"
$ git pull --rebase           # Stahneme a zaclenime si zmeny "ze serveru" do lokalniho repositare
$ git push                    # ... a odesleme "master" na server 

Nevěšte hlavu, jsou-li pro vás uvedené kroky a odkazy typu „a to bychom to mohli udělat ještě jinak!“ matoucí. Práce s paralelními větvemi je základem pracovních postupů v Gitu, a z pohledu koncového uživatele jeho největší výhodou pro efektivitu a produktivitu práce. Je ale třeba se ji učit a zkoušet, pak jde sama od sebe. Největší chybou, které při své konzultační a „osvětové“ praxi vidím, je využívání Gitu jako Subversion 2.0, tedy nekoordinovaná práce v master větvi, která s sebou přináší konflikty a nekonečné „koleje“ merge commitů typu Merge branch 'master' of ..., jak hezky vidíte z obrázku níže.

GITx5

Jak případně poznamenává autor v příslušném článku, „vypadalo by to mnohem lépe, kdybychom využili git-rebase pro přeskládání commitů, místo abychom je slučovali, ale ten, kdo vytvořil takovou historii, to v té době ještě s Gitem moc neuměl“.

V příštím článku se zamyslíme nad tím, co přesně znamená, že Git je „distribuovaný“, resp. „decentralizovaný“ systém na správu verzí, a jaké to má důsledky pro naši každodenní práci s repositáři.

Karel Minařík

Karel Minařík navrhuje a programuje webové stránky a aplikace,
poskytuje konzultace a školení v oblasti vývoje pro web a žije v Praze
se svojí ženou a dvěma dcerami.

Školení Google Analytics pro pokročilé

DW - Školení Google Analytics
  • Jak využít nové funkce Google Analytics
  • Vyhodnocování kampaní díky používání Multichannel funnels
  • Kde návštěvníci vašeho webu utíkají z objednávacího procesu.
  • Nebudete opakovat časté chyby při vyhodnocování dat o návštěvnosti.

Detailní informace o školení Google Analytics pro pokročilé »

Přehled názorů

a bez toho „evangelizování“ by to nešlo?
xurfa 28. 12. 2009 04:51
Nový
├ 
Re: a bez toho „evangelizování“ by to nešlo?
Aleš Roubíček 28. 12. 2009 07:42
Nový
│
└ 
Re: a bez toho „evangelizování“ by to nešlo?
xurfa 28. 12. 2009 15:53
Nový
│
 
└ 
Re: a bez toho „evangelizování“ by to nešlo?
Michal 12. 1. 2011 16:15
Nový
└ 
Re: a bez toho „evangelizování“ by to nešlo?
Karel Minařík 28. 12. 2009 08:15
Nový
 
└ 
Re: a bez toho „evangelizování“ by to nešlo?
xurfa 28. 12. 2009 14:56
Nový
 
 
└ 
Re: a bez toho „evangelizování“ by to nešlo?
Martin Malý 28. 12. 2009 15:17
Nový
 
 
 
└ 
Re: a bez toho „evangelizování“ by to nešlo?
xurfa 28. 12. 2009 15:52
Nový
 
 
 
 
├ 
Re: a bez toho „evangelizování“ by to nešlo?
Martin Malý 28. 12. 2009 17:06
Nový
 
 
 
 
│
├ 
Re: a bez toho „evangelizování“ by to nešlo?
Renda 28. 12. 2009 19:17
Nový
 
 
 
 
│
└ 
Re: a bez toho „evangelizování“ by to nešlo?
xurfa 29. 12. 2009 05:43
Nový
 
 
 
 
│
 
└ 
Re: a bez toho „evangelizování“ by to nešlo?
Martin Malý 29. 12. 2009 08:33
Nový
 
 
 
 
└ 
Re: a bez toho „evangelizování“ by to nešlo?
Michal 12. 1. 2011 16:18
Nový
číslování revizí
lupen 28. 12. 2009 08:42
Nový
├ 
Re: číslování revizí
abtris 28. 12. 2009 09:05
Nový
│
└ 
Re: číslování revizí
Aleš Roubíček 28. 12. 2009 09:41
Nový
│
 
└ 
Re: číslování revizí
Almad 28. 12. 2009 09:48
Nový
└ 
Re: číslování revizí
Karel Minařík 28. 12. 2009 15:04
Nový
 
└ 
Re: číslování revizí
Tom 28. 12. 2009 15:51
Nový
 
 
├ 
Re: číslování revizí
David Majda 28. 12. 2009 16:01
Nový
 
 
│
├ 
Re: číslování revizí
rater 28. 12. 2009 16:07
Nový
 
 
│
└ 
Re: číslování revizí
Karel Minařík 28. 12. 2009 16:24
Nový
 
 
│
 
└ 
Re: číslování revizí
David Majda 28. 12. 2009 18:24
Nový
 
 
│
 
 
└ 
Re: číslování revizí
Karel Minařík 28. 12. 2009 23:40
Nový
 
 
└ 
Re: číslování revizí
Karel Minařík 28. 12. 2009 16:09
Nový
 
 
 
└ 
Re: číslování revizí
Tom 29. 12. 2009 15:30
Nový
 
 
 
 
└ 
Re: číslování revizí
Karel Minařík 29. 12. 2009 15:53
Nový
subversion 2.0
Martin Soušek 28. 12. 2009 16:09
Nový
├ 
Re: subversion 2.0
Karel Minařík 28. 12. 2009 16:21
Nový
│
└ 
Re: subversion 2.0
ondra.novacisko.cz 28. 12. 2009 16:32
Nový
│
 
├ 
Re: subversion 2.0
Karel Minařík 28. 12. 2009 16:42
Nový
│
 
│
└ 
Re: subversion 2.0
ondra.novacisko.cz 28. 12. 2009 17:10
Nový
│
 
│
 
├ 
Re: subversion 2.0
Karel Minařík 28. 12. 2009 17:25
Nový
│
 
│
 
│
├ 
Re: subversion 2.0
Martin Vanek 28. 12. 2009 20:08
Nový
│
 
│
 
│
│
└ 
Re: subversion 2.0
Karell 28. 12. 2009 20:25
Nový
│
 
│
 
│
│
 
└ 
Re: subversion 2.0
Martin Vanek 28. 12. 2009 20:38
Nový
│
 
│
 
│
│
 
 
├ 
Re: subversion 2.0
Martin Malý 28. 12. 2009 20:45
Nový
│
 
│
 
│
│
 
 
│
└ 
Re: subversion 2.0
Martin Vanek 28. 12. 2009 21:17
Nový
│
 
│
 
│
│
 
 
│
 
└ 
Re: subversion 2.0
Martin Malý 28. 12. 2009 21:36
Nový
│
 
│
 
│
│
 
 
│
 
 
└ 
Re: subversion 2.0
Martin Vanek 28. 12. 2009 22:49
Nový
│
 
│
 
│
│
 
 
│
 
 
 
└ 
Re: subversion 2.0
Martin Malý 28. 12. 2009 23:33
Nový
│
 
│
 
│
│
 
 
│
 
 
 
 
└ 
Re: subversion 2.0
Martin Vanek 29. 12. 2009 10:33
Nový
│
 
│
 
│
│
 
 
│
 
 
 
 
 
├ 
Re: subversion 2.0
Martin Malý 29. 12. 2009 11:45
Nový
│
 
│
 
│
│
 
 
│
 
 
 
 
 
│
└ 
Re: subversion 2.0
Borek Bernard 29. 12. 2009 12:06
Nový
│
 
│
 
│
│
 
 
│
 
 
 
 
 
└ 
Re: subversion 2.0
Inkvizitor 29. 12. 2009 20:28
Nový
│
 
│
 
│
│
 
 
└ 
Re: subversion 2.0
Karell 28. 12. 2009 20:48
Nový
│
 
│
 
│
│
 
 
 
└ 
Re: subversion 2.0
Martin Vanek 28. 12. 2009 21:08
Nový
│
 
│
 
│
│
 
 
 
 
└ 
Re: subversion 2.0
Karell 28. 12. 2009 22:43
Nový
│
 
│
 
│
├ 
Mergování
Franta Kučera 29. 12. 2009 01:20
Nový
│
 
│
 
│
│
└ 
Re: Mergování
Karel Minařík 29. 12. 2009 09:28
Nový
│
 
│
 
│
│
 
├ 
Re: Mergování
Borek Bernard 29. 12. 2009 13:00
Nový
│
 
│
 
│
│
 
│
└ 
Re: Mergování
Karel Minařík 29. 12. 2009 13:19
Nový
│
 
│
 
│
│
 
└ 
Re: Mergování
Franta Kučera 29. 12. 2009 16:45
Nový
│
 
│
 
│
└ 
Re: subversion 2.0
ondra.novacisko.cz 29. 12. 2009 21:41
Nový
│
 
│
 
├ 
Re: subversion 2.0
Martin Malý 28. 12. 2009 17:35
Nový
│
 
│
 
│
└ 
Re: subversion 2.0
ondra.novacisko.cz 29. 12. 2009 21:31
Nový
│
 
│
 
└ 
Re: subversion 2.0
Inkvizitor 28. 12. 2009 22:48
Nový
│
 
│
 
 
└ 
Re: subversion 2.0
uf 29. 12. 2009 14:40
Nový
│
 
├ 
Re: subversion 2.0
setapoux 28. 12. 2009 17:40
Nový
│
 
│
└ 
Re: subversion 2.0
ondra.novacisko.cz 29. 12. 2009 21:18
Nový
│
 
└ 
Re: subversion 2.0
Karell 28. 12. 2009 20:22
Nový
│
 
 
└ 
Re: subversion 2.0
ondra.novacisko.cz 29. 12. 2009 21:21
Nový
│
 
 
 
├ 
Re: subversion 2.0
Karell 29. 12. 2009 21:48
Nový
│
 
 
 
└ 
Re: subversion 2.0
Hok 30. 12. 2009 22:56
Nový
│
 
 
 
 
└ 
Re: subversion 2.0
ondra.novacisko.cz 31. 12. 2009 14:52
Nový
│
 
 
 
 
 
├ 
Re: subversion 2.0
Karell 31. 12. 2009 15:18
Nový
│
 
 
 
 
 
├ 
Re: subversion 2.0
Borek Bernard 31. 12. 2009 16:12
Nový
│
 
 
 
 
 
└ 
Re: subversion 2.0
Hok 31. 12. 2009 17:39
Nový
│
 
 
 
 
 
 
├ 
Re: subversion 2.0
ondra.novacisko.cz 1. 1. 2010 00:58
Nový
│
 
 
 
 
 
 
└ 
Re: subversion 2.0
vandrovnik 3. 1. 2010 11:44
Nový
└ 
Re: subversion 2.0
BostX 28. 12. 2009 23:53
Nový
GIT vs Perforce
Bretislav Wajtr, ml. 28. 12. 2009 18:23
Nový
├ 
Re: GIT vs Perforce
vlk 28. 12. 2009 22:23
Nový
└ 
Re: GIT vs Perforce
Karel Minařík 28. 12. 2009 23:53
Nový
 
└ 
Re: GIT vs Perforce
Ladislav Prskavec 29. 12. 2009 07:56
Nový
 
 
└ 
Re: GIT vs Perforce
Ladislav Prskavec 29. 12. 2009 07:57
Nový
aee4bd941f8b4d9e3921 0c06c44fcb71
Karel Čížek 29. 12. 2009 00:26
Nový
Bazaar
Peter Rybar 29. 12. 2009 13:55
Nový
celkove
uf 29. 12. 2009 14:48
Nový
└ 
Re: celkove
Almad 4. 1. 2010 15:20
Nový
Díky za skvělý článek i seriál
Jan Sládek 2. 1. 2010 16:04
Nový
Díky
Daniel Milde 3. 1. 2010 19:05
Nový
Díky
Kaplan Věroš 3. 1. 2010 22:02
Nový
Mrtvej odkaz
Michal 13. 1. 2011 17:12
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem