Přejít k navigační liště

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

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

Články Různé

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).

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.

Komentáře

Subscribe
Upozornit na
guest
84 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
xurfa

Už jenom z toho dementního postoje „jedině Git přinese všem spásu“ naskakuje normálním lidem husí kůže…

Aleš Roubíček

Zbývá jen otázka, dokázal jses v životě pro něco nadchnou a své nadšení předávat dál ve víře, že to někomu pomůže?

Pokud se ti nelíbí Karlův styl, tak ho prostě nečti. Nkdo tě do toho nenutí.

xurfa

Aha, takže součástí toho, že se pro něco nadchnu je i kálení hnoje na ty druhé? Velmi dementní „logika“…

(P.S. Kdyby ten článek byl napsak kapičku méně fanaticky, dal by se docela i čísti…)

Michal

Moc peknej prispevek.

Zlodej krici chytte zlodeje a to primo pri kradezi….

xurfa

V tom případě je takový článek naprosto k (sprominutím) hov­nu.

Martin Malý

Tak ještě že to zachraňují vaše komentáře…

xurfa

Nevím proč by moje komentáře měly cokoliv „zachraňovat“. Komentáře jsou (na většině slušných webů) korektivem proti tomu, když někdo píše cípoviny; takže jestli jsem se nasraně ohradil, tak plním přesně tuto funkci.

Martin Malý

Na většině slušných webů je rovněž zvykem, že komentátor jasně formuluje své výhrady vůči textu. Tuto funkci neplníte. Plníte leda tak funkci vrhače „dementů“, „hoven“ a „nasranosti“. Abych parafrázoval váš titulek: a bez toho fekálního slovníku by to nešlo?

Renda

No on ani ten fekální slovník (dost dobrý název) mu moc nejde. „Cípoviny“ ??? Když už chci takové slovo použít, musím ho umět napsat.

xurfa

Neumíte číst, své výhrady jsem jasně napsal a totiž to, že mě (na jinak věcném článku) štve, že se v každé druhé větě musí navážet do „konkurence“…

Martin Malý

Číst umím. Jestli nebude spíš problém, že jste to přes veškerou snahu napsal až teď.

Michal

Chtel jste napsat „Diskuze na netu jsou V CECHACH korektivem …“

Ano ano, vetsina lidi v Cechach opravdu nema nic dulezitejsiho na praci nez si lecit sve komplexy neustalymi negativy cehokoli, ono ostatne nejde jen o diskuze ze jo?

lupen

Co se mi na gitu nelíbí je číslování revizí. Na SVN je to krásná lineární řada 1, 2, 3, … Ale ty hashe v gitu jsou takové ošklivé. Je možné to nějak přepnout?

abtris

Prepnout zrovna ne, ale da se napriklad post-commitem, revize spocitat:

git rev-list –all | wc -l | sed „s/[ t]//g“

ulozit nekam do souboru a pouzit napr pri deploymentu.

Ve SVN to stejne delame podobne, pokud chci na serveru napr. zobrazovat cislo revize v aplikaci.

Aleš Roubíček

Taky jsem ukazoval číslo revize SVN, abych věděl, co je venku, ale po přechodu na git to vypadalo hnusně. Nakonec tam mám číslo buildu. CI server po úspěšném buildu vytváří v gitu tag s tímto číslem.

Almad

My používáme git describe, s výstupem jsme vcelku spokojeni ,)

Tom

HG to umí. Je tedy zcela možné mít i u distribuovaných verzovacích systémů. Tohle je nedostatek Gitu. Snad to jednou vyřeší. Je to taky jeden z mnoha důvodů proč jsem dal přednost HG před Gitem.

David Majda

Upřesnil bych to: Mercurial používá k identifikaci changesetů také hashe, ale zároveň je aliasuje na lineární posloupnost čísel. Tato posloupnost může být ale jiná v každé kopii repository, čísla tedy jednoznačně identifikují pouze changesety v lokální kopii.

V praxi to příliš nevadí, protože 90% věcí člověk stejně dělá lokálně. Musí se jen myslet na to, že kolegovi vedle už nesmím poslat číslo, ale hash.

rater

presne tak +1

David Majda

Já třeba docela často hledám konkrétní changeset přes hg log (popř. hg log -k). Vypadne na mě něco takového:

changeset:   22:c170698a4a26
tag:         tip
user:        David Majda 
date:        Sun Nov 01 21:01:04 2009 +0100
summary:     .bashrc: Added workaround for https://bugs.launchpad.net/vim/+bug/402188.

Když si pak chci zobrazit od toho changesetu diff, revertnout ho apod., tak nemusím z terminálu copy-pastovat hash (tj. sahat na myš, což je pro mě při práci v terminálu něco jako pro počítač page-fault), ale stačí použít -r 22, což napíšu v pohodě ručně.

Několikrát jsem už taky v historii doloval něco složitějšího a potřeboval jsem si přitom poznamenat několik konkrétních changesetů, abych s nimi později něco udělal. Opět je to pohodlnější pomocí čísel (můžu poznamenat třeba na papír).

Obyčejná čísla jsou proti hashům zkrátka na práci příjemnější.

Tom

Neumí a pak říkáte, že umí? Mercurial má lineární číslování a má i hashe.

Lineární číslování má smysl, když existuje nějaký centrální repositář, tak je jednodušší se bavit o nějakých číslech než o hashi. Mercurial má neměnitelnou historii, takže se nestane, že by se nějak v centrálním repositáři ty čísla proházely.

Viděl jsem u Git projektu, že prostě do každého commitu dali číslo, aby to bylo pro lidi jednodušší se na to odkazovat.

Toto je prostě nevýhoda Gitu. Měl byste trochu změnit ten svůj přístup, že Git je to nejlepší co je a vše ostatní je špatný.

Martin Soušek

„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.“

Šlo by to více rozvést? Tedy co je konkrétně špatně a jak to má být správně? Co je nekoordinovaná práce v master větvi? Z obrázku bohužel nic „hezky nevidím“ :(

ondra.novacisko.cz

Nevím, co je killer feature, ale u nás v Subversion se běžně pracuje tak, že si vyrobím branch celého trunku, pak si stáhnu lokálně vše, na čem budu pracovat, a co potřebuju k přeložení projektu. Při branchování se mohu i přepnout v tomtéž WC.

Následně si pracuji na své větvi a když to chci zamergovat, tak to nejdřív merguju k sobě a následně to přemerguju do trunku, s tím, že to pořeší i změny provedené mezitím. Pokud branch dále už nepotřebuju, tak ho smažu.

Branchování přitom v SVN nic nestojí, bez ohledu na velikost stromu. Proto takhle může pracovat každý uživatel. Přímo v trunku se nepracuje, dělají se v něm jen hotfixy. A i tak lze případný hotfix v půlce práce branchnout, pokud je hodně složitý.

Distribuovanost u repozitáře nám nechybí, naopak centralizace má výhodu, zvlášť pokud je server denně zálohován. Rychlost taky není problém.

Je hezké kritizovat Subversion od člověka, který v něm neumí dělat :-D
A to popisuju praktiky v Subversion 1.5, protože dvojka se ke mě ještě nedostala.

ondra.novacisko.cz

Leckdy kecy. Ano. Bože! Jsou to nástroje a někteří je používat umění, někteří ne. Není problém nástroje, že jej někteří neumí používat. Ano, GIT člověka možná nutí vytvářet branche, ale… kde?… Stejně nakonec musí v centrální databázi, protože nikdo nemá náladu lovit jeho kód v době, kdy náhodou onemocní, nehledě na to, že to má v náplni práce. U SVN má prostě napsáno, že před odchodem musí všechno commitnout a basta. Bez ohledu na to, jestli si vyrobil branch. Pořád je lepší, když commitem něco rozbije, než když to zapomene na lokále. V prvním případě se to dá přeplácnout starší revizí, v druhém případě nastupují crackovací nástroje (zaheslovaný comp je povinnost) nebo vytahování hesel z nemocného nešťastníka.

„Tvrzení, že „branchování v SVN nic nestojí“ je úžasný vtip.“
Vtipnej ste vy

„Branchování ne, ale to mergování, to někdy bývá horší, co říkáte? :)“
Mergování byl, je a bude vždycky problém. Mergování není věc verzovacího nástroje, ale věc mergovacího nástroje. Pokud jde o správné zamergování, tak já používám Eclipsovský diff, který samozřejmě všechno zvládne automaticky, a řeším jen konflikty. I tak se problémům nevyhnu, protože mergování prostě nelze vždy dělat hloupě bez znalosti kontextu zdrojovýho kódu. Ale v tom se obávám GIT mi nepomůže.

Ale mergování přece není těžké. Vyrobí patch mezi dvěma revizemi v trunku a aplikuje ho na branch. Vyrobí patch mezi branchí a trunkem a aplikuje na trunk? Kde je problém? V čem vidíte problém? My to zvládneme bez podpory v SVN, protože repozitář jede (bohužel) na 1.4. Od vyšších verzí je tam podpora, že si to pamatuje čísla revizí od kterých byl merge proveden. I tak se to dá bez problému zvládnout, pokud si to jedno číslo, totiž číslo revize ve které se merguje, zapíše do komentáře. Nic víc.

Martin Vanek

No ja stejne jako novacisko nechapu jak muze git byt prospesnejsi pri mergeovani nez jakakoliv konkurence. Predpokladam, ze se nebavime o trivialnim mergi bez konfliktu. To ma git umelou inteligenci, ktera vydedukuje spravny vysledek z pruniku dvou (a vice) zmen stejneho kodu? Hadam ze ne, proste jen prodpokladate styl vyvoje kdy se nikdo nikomu nehrabe v kodu a kazdy si jede „na vlastnim pisecku“. Kombinace prace nad lokalni repository a „navadeni“ k branchovani (kterehoz uzitecnost je v realu skutecne casto podcenena) vede ve vysledku k potrebe vetsiho pushe do centralni repository a tim padem k pravdepodob­nejsimu vytvoreni megakolizi a o ty tu jde predevsim, ostatni je syntakticka omacka.

KarelI

Jak lokalni branch zpusobi vetsi pravepodobnost megakolize oproti branch na serveru?

Martin Vanek

Predpokladam ze lokalni zmeny jednou popupuji na central at uz head nebo branch. Do toho sameho ovsem sve zmeny pushuji i ostatni, takze cim vetsi kumul zmen, tim vetsi legrace s konflikty. Tohle nemuze vyresit zadny system at uz distribuovany nebo centralni ci jakykoliv.

Martin Malý

Položím otázku téměř filosofickou: Kde přesně je v distribuovaném decentralizovaném systému ten „central“, kam „jednou“ poputují „lokální změny“?

Martin Vanek

Takze vy v gitu nesdilite kod s nikym jinym, nebo mate nekde v metadatech gitu IP adresy peeru?

Martin Malý

Zkuste nejprve odpovědět na položenou otázku, možná zjistíte, že to není jen „slovíčkaření“, ale že je v ní odpověď i na další Vaše připomínky v této diskusi. Napovím analogií: Pro středověkého člověka byla Brunova představa mnohosti světů, v němž neexistoval žádný „střed vesmíru“, okolo něhož by se zbytek točil, mentálně neuchopitelná – neměla žádný pevný řád, a mozek tíhne k řádu, kterého se může držet.

Martin Vanek

Dekuji za prirovnani ke stredovekocloveku, nicmene obsah vasi lokalni repository je celemu vesmiru platny stejne jako surmovce cerite supernova. Bez well known spolecneho remotu (tedy centralu) se proste neobejdete.
Uplne stejne jako clanek juchajici nad v podstate trivialnim blbnutim s branchema (opet podotykam, ze jsou obvykle tezce nedoceneny a poduzivany) a zastirajici fakt, ze skutecny problem neni ve snadnosti spravy vetvi, ale v reseni konfliktu, zastirate ted vy fakt, ze k realne praci byt i jedineho cloveka na vice strojich, potrebujete spolecny remote. Pro takovy trivialni pripad by vam takrka stacil „stary spatny“ sdileny filesystem, pac kolizi sam se sebou snad vyrobite ztezi. K cemu by byl takovy github?

Martin Malý

Pro samou snahu nachytat někoho na švestkách a dokázat, že předměty těžší než vzduch nemohou létat, jste bohužel odpověděl dřív než jste se zamyslel, že? Tak jinak: Já nic nezastírám (a tím míň praktickou užitečnost sdíleného remote prostoru), já se vás ptám, kde chcete v decentralizovaném distribuovaném systému najít tu „centrální autoritu“, na niž se odvoláváte, a která by dle vás měla řešit megakolize, které vzniknou tam, kde se nashromáždí moc commitů? Je opravdu tak těžké přijmout představu, že jich může být víc, že mohou vznikat a zanikat podle potřeby, spojovat se a zase rozdělovat? Že v takovém systému nemusí vznikat konflikty takového typu, jaké popisujete, protože je možné nastavit procesy jinak? (Technicky to tu popsal Inkvizitor.)

Zkuste na DCVS nahlížet jako na vývoj Linuxu/GNU (nemyslím teď samotný kernel): Nemá „centrální repository“, má stovky repository na tisíce programů, a z těchto repository si vybírají správci balíčků a distribucí potřebné soubory pro své repository. A když se správce jednoho konkrétního balíčku rozhodne, že si udělá kolem svého SW distribuci, tak nebuduje celou paralelní vývojářskou síť, v níž by on byl CENTRAL, ale stáhne si od ostatních to co potřebuje, vyřeší si konflikty – a postupuje tak při každém update. Je to stejný princip, jen o úroveň výš.

Martin Vanek

Svestky stranou a „centralni autoritu“ na reseni kolizi jste si prave vymyslel vy. Konflikt si v kazdem me znamem VCS resi nestatstnik ktery zrovna merguje svuj kod s kodem ostatnich.

Inkvizitor ve svem informativnim sedm radku dlouhem (prispevku narozdil od vaseho opletenem obecnymy a nabubrelymy vyroky) o pouzil sestkrat vyraz verejny/centralni repository. To celkem mluvi za sebe.

To co popisujete v druhem odstavci popisuje situaci kdy je pouze jednosmerne odsavano z mnoha ruznych remote repositaru a poreba verzovani je 0.

Martin Malý

Ocituji: „Predpokladam ze lokalni zmeny jednou popupuji na central at uz head nebo branch. Do toho sameho ovsem sve zmeny pushuji i ostatni, takze cim vetsi kumul zmen, tim vetsi legrace s konflikty.“ Otázka: „Kde je v DVCS ten centrál, do kterého pushují i ostatní?“ (Pomůcka: Inkvizitor hovořil o vybírání shora, nikoli o tlačení zespoda…)

Borek Bernard

Martine, centrální repozitář vyplývá z kontextu nastoleného diskutujícími v tomto threadu (snaží se zjistit, jak jim git pomůže s mergováním v svn-like workflow). Na obecné úrovni máš samozřejmě pravdu, jen mám pocit, že o tom toto vlákno není (nebo aspoň do určitého okamžiku nebylo :)

Inkvizitor

Pojem „centrální“ jsem možná nezvolil moc vhodně. Zrovna tak jsem mohl napsat „produkční“, „oficiální“, „referenční“… Rozdíl je asi hlavně v tom, že role „hlavního“ repozitáře není podepřena nějakou automaticky danou prioritou jakožto vlastností VCS, ale právě procesem, který dodržují lidé (a případně nějaké automatizované nástroje).

Co se týče věcné stránky sporu, domnívám se (jako někteří jiní), že zásadní výhoda z hlediska správy konfliktů plyne právě z nahrazení operace merge operacemi rebase a cherry-pick, ikdyž jsou i nevýhody; třeba časová režie opakovaného rebase a ztráta informace při umělé linearizaci historie projektu.

KarelI

Aha, takze problemem jsou velke lokalni zmeny, ne lokalni repository. V tom pripade to ovsem je vec politiky tymu, ne VCS.
Ze zkusenosti musim rict, ze v tomhle zrovna SVN praci vubec neusnadnuje – viz castecne commity z jednoho souboru v minule diskuzi. Aneb kdyz chci v SVN dostat na server aspon neco, tak to stoji hodne trapeni, vykopirovavani atd…
A dovedu si predstavit, ze by to slo delat jeste lepe nez v gitu :-)

Martin Vanek

Tak na zastecne komity je tu integrace s IDE, ale o to ted nejde. Jde o to, ze jsem z clanku a s diskuze mel dojem ze git prinasi neco genialniho v problematice mergeovani konfliktu oproti svn (a potazmo s cvs) a jak to tak vypada jedna se o stale samy (neresitelny) problem, az na to, ze v gitu musim diky/kvuli distibuovanosti navic pushit, tedy o prikaz vice, coz se asi muze u nekterych typu projektu hodit, nicmene v korporatnim pouziti mi prijde spis prace navic.

KarelI

Uz ten vyraz castecny commit napovida, ze by ho mohl resit nastroj, ktery dela commity, ale proti gustu…
Nejlepsi reseni konfliktu je takove, kdy k nim nedochazi – napriklad tak, ze si vyvojari muzou predat casti kodu mezi vetvemi jeste nez dojde k mergovani do nejakeho spolecneho trunku. Udelal jsem si ted maly test, SVN 1.6.6 to nezvladlo pokud jsem nezadaval rozsahy revizi. V kombinaci s tim, ze mi TSVN neukaze co kam jsem uz mergoval je to dost pruda.
Cili SVN mi moji snahu predchazet konfliktum nijak neusnadni, naopak musim se snazit ja, aby to nervalo v pripadech, kdy se o konflikt nejedna. Git udelal presne co jsem chtel a nestezoval si na nic. Takze asi tak.

František Kučera

>> Mergování byl, je a bude vždycky problém.
>Věřte nevěřte, nemusí to tak být.

„Mergování“ je problém z principu. A nezachrání to ani sebegeniálnější verzovací systém – leda že by to byla umělá inteligence, ale to by za nás pak počítač mohl rovnou programovat a my bychom nemuseli dělat nic. :-)

Ono totiž u slučování nejde až tak o tu technickou/formální stránku, ale o tu obsahovou – že vůbec máme různé verze nějakého souboru (souborů) a ty je potřeba sloučit. Následně je potřeba vyzkoušet, jestli ta sloučená verze jde zkompilovat a otestovat ji – to sloučení může sice krásně proběhnout, ale při kompilaci se např. ukáže, že kolega přepsal nějaké rozhraní a moje třídy, které by ho měly implementovat ho neimplementují (třeba tam chybí nějaká metoda nebo je přejmenovaná)… a to jsou věci o kterých verzovací systém neví a ani nemůže vědět → to je pak práce pro člověka.

IMHO je lepší se nejdřív snažit:

– aby si jednotliví vývojáři „nelezli do zelí“ – nějakou ucelenou část aplikace vyvíjí v jednu chvíli jen jeden člověk.

– pokud to není možnné, tak se udržovat co nejvíc „online“ mít vždy aktuální verzi a nedopustit, aby se větve jednotlivých vývojářů příliš „rozjely“.

A až když to nejde, tak nastupuje to „mergování“ – což je ale práce navíc a opruz (z výše uvedených důvodů) vždycky – i s tím úžasným Gitem nebo Mercurialem. Je to víc o organizaci a rozvržení práce než o verzovacím systému…

Borek Bernard

Super komentář, který by možná měl být přímo v článku – a na něco podobného jsem se vlastně včera večer chtěl zeptat taky a jsem rád, že diskuze došla až sem.

Mně totiž taky připadá, že dokud někdo neudělá normální a objektivní porovnání stejných scénářů v různých VCS, zůstane rétorika o snadném mergování jen rétorikou. Asi by nebylo těžké prokázat, že mergování v SVN je v některých případech přinejmenším problematické (tvůj druhý odkaz by mě od SVN asi úplně odradil), ale co třeba Perforce? TFS? Je mergování v gitu při podobném workflow jednodušší nebo na stejné úrovni? Nebudou naopak některé centralizované systémy dokonce lepší kvůli explicitnímu uchovávání informací např. o přejmenovaných souborech?

To jsou asi všechno otázky, na které se nedá odpovědět jednou větou, ale právě na jejich základě bych se rád rozhodoval. Což takhle po Novém roce zkusit nějaké takové porovnání udělat?

František Kučera

>> „Mergování“ je problém z principu. A nezachrání to ani sebegeniálnější verzovací systém (…)
>Ano, v tom máte samozřejmě pravdu.

Já jsem právě reagoval na „Věřte nevěřte, nemusí to tak být.“
Ale nechme toho, to je slovíčkaření.

> Pochopitelně, na to se dá říct, že jsme všichni fanboys a blbci a že to určitě s SVN neumíme etc etc.

Nezastávám se Subversionu – sice si nemyslím, že by byl úplně odepsaný a měl by zmizet, ale distribuované systémy jsou (většinou) výhodnější. Nezastávám se tu ani Mercurialu, který je můj oblíbený. Ale abych přece jen trochu přispěl k diskusi, napsal jsem: Verzovací systémy – svn, git, hg – svatá válka?

> Kdyby si někdo dal tu práci a složitější merge vyzkoušel v Perforce
S P4 jsem dělal asi tři roky… a občas jsem si říkal „proč radši nepoužíváme ten Subversion“ :-) Dneska bych dal asi přednost Hg (případně Gitu) před Perforcem a to nejen kvůli tomu, že za P4 se musí platit. Zajímavější by spíš bylo vyzkoušet si reálnou práci s ClearCasem – ale ne s ním samotným, ale s celou tou sadou nástrojů od Rationalu (IBM) – absolutní integrace od IDE, přes verzovací systém, „Bugzillu“ až po testovací nástroje.

ondra.novacisko.cz

„To se commituje i napůl rozdělaná práce? A do jaké větve?“

Ano!

Pokud je zřejmé, že se to do konce dne nestihne, pak si vývojář vyrobí branch (v Branches má každý právo si založit libovolné množství větví), switchne se do něj a commitne to do něj. Operace přes GUI na jednu nebo dvě minuty.

To jestli se vyrábí centrální, nebo lokální branch je jedno. Síť je relativně rychlá a výhoda centrální branche je v tom, že centrál je denně zálohován a na práci vývojáře může klidně někdo navázat.

Martin Malý

Jen k tomu „nemocnému vývojáři“ – jednak to je opravdu otázka nastavení procesů, jak píše Karmi, ale spíš by mě zajímalo, jak s tímto přístupem chcete nějak rozumně vyvíjet SW, na kterém se podílí několik desítek lidí na různých místech v různých časech a ve volných chvílích (typicky všechny komunitní projekty)? Čím dál víc firem opouští model „vývojář sedí osm hodin v kanceláři u PC a odevzdává denně svých XXX řádků kódu“, přechází z centrálně řízených a plánovaných projektů na jiné způsoby (decentralizace, iterace vývoje místo plánu apod.) a tam je Vámi popsaný model poněkud anachronický a kontraproduktivní.

ondra.novacisko.cz

To je hezká představa, ale utopie. I když programátor pracuje vzdáleně, přes VPN a kdy se mu zachce, stejně by měl mít povinnost jednou denně commitnout „někam“ svých XXX řádků. Už proto, aby jeho práce byla nějak kontrolovatelná. V naší firmě provádíme Scrumování a sprintování, což se vyznačuje zejména každodenní zhodnocení práce před celým týmem. Je to v celku osvěčená technika (standup trvá cca 15minut, takže žádné velké zdržování). Pokud se pracuje externě, pak se to řeší přes video nebo hlasovou konferenci, v horším případě přes Jabber.

Právě že achylovou patou celého OpenSource programování je ten, že na programu dělá blíže nezjištěné množství vývojářu, bez zřejmé koncepce, bez zodpovědnosti, jako konička se svým vlastním přístupem k problému, který není vždy žádoucí. Chápu, že pak existuje nutnost nějakých nástrojů, jak tyto vývojáře nějak sjednotit. Nadruhou stranu, tam bych viděl problém celého Linuxu, tedy roztříštěnost, a tomu ještě napomáhá distribuovaný verzovací systém.

Inkvizitor

Merge je obecně zlo, někdy možná nutné, ale většinou nikoliv. Dá se to vyřešit i jinak – např. každý vývojář má svůj lokální repozitář a veřejný repozitář, do kterého dělá pravidelně push z toho lokálního, na kterém dělá pravidelně rebase oproti centrálnímu repozitáři. Lokálně si vyřeší konflikty oproti centrálnímu repozitáři a správce centrálního repozitáře přejímá commity z veřejných repozitářů všech vývojářů pomocí operace cherry-pick. Tak se vyřeší případná absence vývojářů, kteří uveřejní commity, které považují za finální, předejde se drtivé většině špatně řešitelných konfliktů a historie centrálního repozitáře zůstane krásně lineární. Výhoda distribuovaných VCS je právě v tom, že v nich jde takto nastavovat procesy podle potřeby.

uf

Tak nejak si to predstavuju s Mercurialem

setapoux

svn copy blabla/trunk blabla/branches/my­branch – tohle, že nic nestojí? No nevím…

Na druhou stranu buďte všichni rádi, že Vás nenutí používat ClearCase.

ondra.novacisko.cz

1) používám GUI
2) Vlastní operace kopírování neprovádí, pouze vytvoří něco jako symlink.

KarelI

> Branchování přitom v SVN nic nestojí, bez ohledu na velikost stromu

Sam pisete, ze si branch musite stahnout nebo prepnout. Prvni je prinejmensim linearni ve velikosti kodu, druhe linearni v poctu adresaru. Na male projekty to staci, ale u velkych to zacne byt docela „drahe zadarmo“. Pak uz si rozmyslite, jestli branch udelate nebo ne. Rozhodne je to neco, v cem SVN usera omezuje.

ondra.novacisko.cz

Používám GUI. Tortoise SVN tohle zvládne přes kontextové menu v exploréru. Stačí si jen zvoli jméno branche. Zbytek se udělá samo. Nedávno jsem to udělal v repozitáři, který má několik desítek tisíc souborů, číslo revize má na začátku pětku a další čtyři čísla a celý repozitář má kolem půl giga. Operace trvala asi 5sekund, přičemž mám k dispozici síť 512KB.

WC byla samozřejmě před branchem už stažení.

KarelI

Jo, tak samotne zalozeni 5s jeste jde. Switch do existujici ale trva mnohem dele, radove minuty. A nevisi to jen na pripojeni. Nevim cim to je, mozna ze velikosti rep, nase ma 13GB…

Hok

Nechapu jak nekdo muze rikat, ze prace s SVN je rychla, nebo nedej boze prijemna. Delam na trosku vetsim projektu ve kterem mame hodne „hlavnich“ vyvojovych vetvi + spoustu personalnich.

Ano, da se s tim pracovat. Ale je to opravdu neprijemny zazitek. Navic pokud dojde k situaci kdy je potreba zamergovat jednu z vyvojovych vetvi do trunku tak je to vetsinou prace pro jednoho zkuseneho programatora na nekolik hodin – a to i diky tomu, ze svnku proste spousta veci strasne trva. Nemluve o situaci kdy z vyvojove vetve nekdo primergoval prioritne. (A ne svn:mergeinfo je sice fajn, ale nic moc to neresi)

A nedej boze kdyz potrebuju behem merge kouknout na historii nejakeho souboru, to si nekdy pockam i par minut.

No celkove po precteni tohoto vlakna jsem nabyl dojmu ze jsou jenom dve moznosti jak muze vesmir fungovat. Bud s SVN pracuju (a dalsich 150 lidi v nasi firme) strasne blbe, nebo nekteri z prispevovatelu s SVNkem nikdy nepracovali na vetsim projektu. (A priznavam ze pripoustim existenci obou vesmiru zaroven)

ondra.novacisko.cz

Zkuste připustit variantu, že spoustu lidí pracuje v SVN, aniž by přesně věděla, jak se v něm pracovat má.

Doufám, že třeba víte, že mergovat do trunku je nutné tak, že nejprve zamerguju změny v trunku do svého branche a pak to přemerguju do trunku. Tím se vyhnete všem těmto problémům, o kterých píšete.

A pomalost jsem nepoznal ani na projektu, který má desítky tisíc souborů a desítky tisíc revizí. Pomalost ve smyslu běžná reakce na příkaz do jedné dvou sekund, při významěnjších operací (jaku merge stromu) do deseti sekund. Nevím, jaké máte vy zkušenosti s časy, ale tohle jsou pro mne běžné časy.

Historie… teď jsem to zkoušel, na VPNce, rychlost downloadu 512kB. nechal jsem si vytáhnout historii celého stromu včetně branchů a trunků za poslední měsíc filtrovaný na moje jméno. cca 15s, hlavně díky pomalosti linky (filtrování totiž provádí až klient). Revizí tam bylo mnoho. Na páteři by to bylo za doslova pár sekudu.

Nevím, o jakých časech mluvíte.

KarelI

Co se tyce casove narocnosti, asi nezbyva nez to uzavrit s tim, ze jen v teto diskuzi je nas nekolik, kteri maji svn strasne pomale a to ze vam to jede rychle nas nespasi. Mozna je to velikosti rep nebo strukturou adresaru, kdo vi, ale holt je na to svn nepouzitelne kdezto git ano.

> nejprve zamerguju změny v trunku do svého branche a pak to přemerguju do trunku. Tím se vyhnete všem těmto problémům

Tohle je presne styl SVN, ze vas to nuti delat veci nejak, jen aby to fungovalo. Ve vysledku porad obchazite nejake problemy a jen si tim zpusobujete dalsi. Napr. zde, kde je nutne delat 2× tolik casove umorne prace s presne definovanym postupem, zadne merge mezi vetvemi atd. protoze jinak je mergeinfo k nicemu.

Borek Bernard

Workflow s trunkem a branchí, které popisujete, v SVN bohužel problematické je, viz http://blogs.open.collab.net/…on-merg.html

Hok

Ano pripoustim, ze spousta lidi s SVN pracuje … rekneme neinformovane. Ale troufam si tvrdit, ze toto u nas vetsinou problem neni.

Ano vim, ze „je nutne“ zamergovat zmeny z trunku do branche a potom teprve primergovat. Ale to nic nemeni na tom ze obcas potrebujem prioritne commitnout revizi z branche na trunk mimo predem dany rozvrh. A to je vetsinou misto ve kterem se SVN system zacina rozsypavat jak domecek z karet. (Prehanim, nerozsype se, jenom zacnou byt veci trosku komplikovanejsi)

A bohuzel nevim o jakych casech mluvite Vy. Kdyby to v mem pripade bylo tak jak rikate, tak bych si na svn asi ani tolik nestezoval. Ale v nasem pripade to je proste radove pomalejsi. Show history zabere i nekolik minut, kdyz ma zrovna den (a rychlosti spojeni to rozhodne neni).

ondra.novacisko.cz

To mergovani do branche je hlavně proto, aby se pořešili změny v trunku v rámci Vaši branche. Dělá se to proto, ne že by to SVN nezvládal, nebo že je to nějaká obchůzka. Dělá se to proto, že žádný merge není tak inteligentní, aby vždy zamergoval správně strukturu zdrojaků. Proto se používá postup

1) Zamergovaní trunku do branche
2) Přeložení
3) Vyzkoušení
4) Commit
5) Překlopení branche do trunku.
6) Commit v trunku.

Pokud děláte commit přímo z branche do trunku, koledujete si o malér už proto, že nemáte představu, jaké změny tam kdo udělá mezi tím, co uděláte v trunku update a commit. Ano pak nastane varianta, update, merge, update, commit, která v závislosti na změně mezi mergem a druhým updatem nemusí dopadnout dobře. Protože změny, které tam někdo provedl vlastně patří před první update, zatímco vy je uděláte až po merge, což je z pohledu historie špatně. Pokud jsou ty změny závislé, pak se to rozbije. Bohužel, neumíte mergovat, není to problém SVN.

Naopak výše uvedený postup způsobí, že pokud mezi merge a commitem do trunku dojde ke změne, musíte se vrátit k bodu jedna a celý postup opakovat. Proč? Protože je to konflikt. Výhodou ale je, že nemusíte opakovat celý merge, protože ten částečný už máte udělaný, mergujete jen ty změny, které proběhly mezi body 1. až 7. během prvního kolečka.

Tohle jsou všechno problémy dané tím, že víc lidí pracuje na tomtéž. Všechny tyhle konflikty musíte řešit, ať už implicitně, nebo explicitně. A pokud vám vadí množství těch kroků. které musíte udělat,… linuxák by si měl být schopen napsat skriptík ne? Takový, který to zvládne vše automaticky (kromě bodů 2 a 3). bez další kooperace s uživatelem.

Nevěřím, že GIT zvládne mergování lépe. Určitě si musíte nejprve updatnout lokální repozitář, násleně zamergovat svůj branch a pak to poslat na server ne? Tudíž totéž v bledě modrém.

vandrovnik

Kdysi po nějaké aktualizaci serveru začalo být i moje SVN pomalé – ukázalo se, že za to může volba KeepAlive v httpd.conf, která po aktualizaci byla nastavená na Off. S nastavením na On je rychlost vyšší minimálně o řád.

BostX

Tiez som mal na zaciatku tento problem. Odpoved je jednoducha:
1. Commituj/bran­chuj tak casto ako chces hoci aj kazdu bodkociarku (niekedy to ma vyznam pri bisecte) ale nie do upstreamu, ale lokalne, do tvojich privatnych branchov
2. Na sync lokalnych branchov s upstreamom nepouzivaj ‚git merge‘ ale zasadne ‚git rebase‘
3. Nauc sa pouzivat ‚git commit –amend‘, ‚git rebase –interactive‘ a ‚git cherry-pick‘

Bretislav Wajtr, ml.

Zajimalo by me jak by jste porovnali GIT versus Perforce… pokud teda nekdo znate oba systemy. Zatim jsem ze dvou jiz napsanych clanku o Gitu vypozoroval, ze toho ma s Perforcem celkem dost spolecneho. (Doufam ze me ted znalci neukamenuji). Pravda ze Perforce nam tedy obcas rika „jak“ veci delat, ale zatim to tedy beru pozitivne, protoze nas je opravdu mnoho a kodu uplne silene. Napr. uz si nedokazu predstavit praci bez tzv. Changelists – (pravdepodobne to same co je v gitu Index) – zmeny se daji rozdelit do changelistu a submituje se potom jeden changelist jako celek. Krasne se pak hleda co se se souborem delo… ma GIT napr. nejake vymakane GUI? Ptam se jen kvuli vyhledavani zmen… na zbytek staci radka, ale pohodlny search je v urcitych situacich podstatna vec… Prosim nereste otazku penez… Cena Perforcu ho odsuzuje k vetsim projektum, ale to me nezajima… ted resim problem „co je lepsi na co“, ne „kolik za to dam“

vlk

Porovnajte si sam :
http://versioncontrolblog.com/…e/index.html

http://better-scm.berlios.de/…parison.html

http://en.wikipedia.org/…rol_software

BTW. ja som zatial rozhodnuty urobit upgrade z CVS na Mercurial.

Ladislav Prskavec

Jeste bych pridal ze podpora Gitu je v IDEA a WebIDE od JetBrains,
a osobne mam rad klienta tig pro console (pekny a prehledny) http://jonas.nitro.dk/…screenshots/.

Naopak treba ten NetBeans plugin je skoro nepouzitelny, umi jen par zakladnich prikazu a jeste mi to docela padalo.

29. 12. 2009 8:30 redakčně upravil Martin Malý, důvod: Autor komentáře požádal o odstranění špatně zadaného odkazu
Ladislav Prskavec

sorry za spatny link u IDEA, http://www.jetbrains.com/…control.html

kaja47

Doteď jsem Git používal jako velice hloupé verzovátko. Teprv tenhle článek mi otevřel oči.

pr.rybar

Ma niekto nejake skusenosti s pouzivanim RCS Bazaar? Ako je na tom v porovnani s GIT? Chcel by som vediet nazor niekoho, kto realne oba systemy nejaky cas pouzival.

uf

K cele diskusi:
Na rozdil od jinych se v clanku upozornuje na vlastni firmu-skoleni jen jednou. Jsou jine weby, kde je to podstata clanku.

Kolik vas dela s Mercurialem? Me se libi.
Je distribuovany.
Pro release, buildy a integraci je stejne potreba mit hlavni repozitor, kam clovek da opravdu otestovane OK vysledky, pak nejaky pro caste jeti testu a kazdy clovek by asi mel mit svuj pracovni a svuj zakladni, kde jsou veci pustitelne dal.

Almad

My ve firme jedem na gitu, ale na osobni projekty pouzivam hg. Nevidim mezi temi projekty nejaky zasadni rozdil, akorat s hg se pracuje primeneji.

git je mocnejsi, ale to v 99%tech nepotrebuju a naopak me casto zdrzuje jeho UI.

Honza Sládek

Karmi, děkuji za další skvělý díl seriálu. Tvoje vysvětlení GITu chápu i já (na podobné věci poměrně antitalent) a začínám tak poznávat sílu a krásu GITu. Jen tak dál!

Dundee5

Díky Karmi! Tenhle seriál čtu opravdu velmi rád a doufám, že si ho přečte i hodně project managerů, aby se Git v českých IT firmách trochu víc prosadil.

veros

Zdvořile prosím redakci o zřízení tlačítka „Mě se líbí“, ať nemusím zaplevelovat diskusi.

Michal

„odkážeme na velmi hezké vysvětlení s obrázky“ uz neexistuje, relevantni clanek jsem podle keywords z URL nasel tady: http://www.jarrodspillers.com/2009/08/19/git-merge-vs-git-rebase-avoiding-rebase-hell/

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.