Hlavní navigace

Výlet do říše verzí: RCS - mergování

Petr Baudiš

Po delší prodlevě nastal opět čas podívat se do světa RCS. Dnes se dozvíte, co je a k čemu slouží mergování (a hlavně, jakými všemi možnými způsoby se dá provádět). Budeme si také vyprávět, jak vznikají konflikty, proč vznikají a jak se s nimi vypořádat.

Jak na slučování větví

Často provedeme změny v jedné větvi, načež chceme podobné změny provést i ve větvích jiných (například se jedná o opravu nějaké chyby). Proto by bylo vhodné mít možnost slučovat některé změny s jinými větvemi. Takové akci se učeně říká merge a můžeme takto řešit například i situaci, kdy nám někdo poslal patch proti nějaké starší revizi souboru. Dokonce takovéto věci můžeme provádět hned několika způsoby. Musím ale upozornit, že žádný z těchto způsobů výsledné změny automaticky nezaregistruje! Po sloučení změn tedy musíte sami ještě zavolat ci.

Samozřejmě můžeme příkazem rcsdiff vygenerovat diff mezi revizí před změnou a revizí po změně a pak použít příkaz patch, ovšem rozložení na několik kroků může být nepohodlné a hlavně je dosti pracné řešit případné konflikty (o nich si povíme za chvíli — ono je to občas pracné i tak, ale méně). Proto je tu příkaz rcsmerge. Ten vezme rozdíly mezi dvěmi revizemi souboru a zahrne je do jeho pracovní kopie. Pokud tak do revize 1.4.2.3 chceme zahrnout rozdíly mezi revizí 1.6 a 1.7 (protože jsme v revizi 1.7 opravili vážnou chybu), použijeme (na souboru obsahujícím revizi 1.4.2.3) rcsmerge -r1.6 -r1.7. Pokud naopak například zjistíme, že úpravy, které jsme provedli v revizi 1.5, se nám úplně nepovedly, a chceme tedy vrátit zpět změny mezi revizí 1.4 a 1.5 (tzv. je revertnout), použijeme rcsmerge -r1.5 -r1.4 (pozor na pořadí parametrů!). Jako poslední příklad si ukážeme mergování patche proti starší verzi souboru — pokud máme patch na verzi 1.3, vrátíme se k ní odpovídajícím příkazem co, aplikujeme patch a následně sloučíme všechny změny až k poslední revizi (dejme tomu 1.7) pomocí rcsmerge -r1.3 -r1.7 — máme nyní opět revizi 1.7, ovšem včetně onoho patche. Výhoda je opět ta, že RCS umí v případných konfliktech chodit mnohem lépe než klasická utilita patch.

Téměř ekvivalentní k rcsmerge je parametr -j (od slova join) příkazu co, pracuje však přímo s revizí daného souboru (tou aktuální nebo předanou jiným parametrem, třeba -r). Často je proto méně flexibilní, na druhou stranu se však tato vlastnost může občas hodit a použití této metody může být také rychlejší a elegantnější; krom toho v CVS se používá prakticky výhradně tato metoda. Samotné použití je jednoduché, jako hodnotu parametru napíšeme rozsah revizí, které chceme sloučit s tou revizí, kterou právě checkoutujeme. Pokud chceme tedy připojit k revizi 1.4.2.3 rozdíly mezi revizí 1.6 a 1.7, použijeme co -r1.4.2.3 -j1.6:1.7. Pokud chceme vrátit zpět změny mezi revizí 1.4 a 1.5, stačí co -j1.5:1.4.

Při mergování patche proti starší verzi souboru si musíme pomoci, protože co nám přepíše aktuální verzi souboru — nejdříve si tedy u revize 1.3 vytvoříme pomocnou větev, do které si uložíme onen patch příkazem ci -r 1.3.1; nyní již stačí sloučit změny v této větvi s poslední revizí souboru příkazem co -j1.3:1.3.1. Na první pohled se tento přístup může zdát podivný a neohrabaný, vyzařuje však určitou vnitřní krásu a eleganci ;-). Způsob, jakým RCS a CVS pracuje s větvemi, není úplně nejšťastnější a některé nedostatky do značné míry uživatele od širšího používání větví odrazují. Ovšem pokročilejší systémy (o kterých si povíme po CVS) často větvení a slučování ovládají mnohem lépe a uživatele se v častém větvení snaží dokonce podporovat. Proto se v některých z nich často setkáme s podobným přístupem, jehož odlesk vidíme v této metodě mergování patchů.

Metoda parametru -j je zvláště vhodná také při slučování celých větví, například pokud chceme sloučit všechny změny v hlavní větvi do pomocné větve, ve které vyvíjíme nějakou zvláště nestabilní funkci. Pokud vynecháme počátek rozsahu revizí, automaticky se doplní poslední revize ještě společná pro obě větve. Tedy například pokud chceme do hlavní větve (1) zahrnout všechny změny provedené ve větvi 1.3.1, zavoláme ve větvi 1 příkaz co -j1.3.1.4, automaticky tak přimergujeme změny mezi 1.3 a 1.3.1.4. Ale nebylo by to RCS, kdyby v tom nebyl nějaký háček. Bohužel totiž nemůžeme tak elegantně mergovat změny opakovaně, poněvadž některé změny by se nám přimergovaly několikrát, což není pěkná představa. Pokud bychom totiž zaregistrovali revize 1.3.1.5 a 1.3.1.6 a chtěli je přimergovat, co -j1.3.1.6 nám kromě toho zkusí opět sloučit do aktuální revize i revize 1.3.1.1 až 1.3.1.4. Proto nám nezbývá, než si při opakovaném slučování pamatovat, co všechno už jsme mergnuli, a psát co -j1.3.1.5:1.3.1.6.

Pozn.: rcsmerge a -j používají ve skutečnosti jako backend příkaz merge, který je sice také součástí distribuce RCS, ovšem lze používat zcela nezávisle. Více viz manuálová stránka merge(1). A merge zase používá jako backend příkaz diff3, o kterém se teoreticky blíže dočtete v diff3(1). Já tuto manuálovou stránku z nějakého důvodu nemám, dokumentace je však součástí i info manuálu k diffu.

O bytostech podsvětních aneb konflikty

Občas slučování změn není zase tak jednoduché. Problém totiž nastane, když nezávisle na sobě ve dvou větvích změníme třeba jeden řádek a teď chceme větve sloučit:

Tabulka č. 398
1.1 1.1.1.1 1.2
Ahoj
Zdravím
Dobrý den
Ahoj
Zdravim
Dobry den
Ahoj
Zdravíme
Dobrý den

Nastává ovšem problém, druhý řádek jsme změnili v obou větvích. Má se tedy při sloučení dát přednost „Zdravim“ nebo „Zdravíme“? To ovšem RCS neuhodne, tedy se zbaběle vzdá, vygeneruje konflikt a nechá problém vyřešit nás. Na konflikt ovšem alespoň patřičně upozorní, jak ve formě chybové hlášky vygenerované rcsmerge či co -j, tak i poměrně výrazným označením ve výsledném souboru (dejme tomu že mergujeme 1.1.1.1 a 1.2 do 1.3):

Ahoj
<<<<<<< 1.2
Zdravíme
=======
Zdravim
>>>>>>>> /tmp/T3PHcpoy
Dobry den

<<<<<<< označuje počátek této nemilé události, následuje ho číslo revize a původní fragment. Ten je ukončen ======= a po něm přichází fragment, který pochází z 1.1.1.1. Všechno uzavírá >>>>>>> a jakési podivné jméno pracovního souboru, na kterém RCS pouštěl merge. Při řešení konfliktů tedy vybereme ten vyhovující fragment (případně je sloučíme nějak inteligentně, třeba do „Zdravime“) a zbylý ASCII art eliminujeme.

Pozn.: údaje za <<.. a >>.. jsou pouze informativní a můžou být libovolně proházené podle toho, jak šíleně zrovna mergujeme; například u CVS bude naopak obvykle jako první jméno souboru (CVS je pokročilejší, takže tentokráte již smysluplné ;-) a teprve na konci číslo mergované revize.

Další pozn.: velmi oblíbeným zdrojem konfliktů bývají keywords neboli klíčová slova. Co jsou zač a jak se vypínají, se dozvíme … po reklamě.


Příště se s RCS rozloučíme povídáním o mocném nástroji jménem klíčová slova. Ta nám umožní se uvnitř souboru dozvědět, že vlastně prošel RCS, a náležitě toho využít. Na závěr pak ještě utrousíme několik pochmurných slov o obludce jménem SCCS.

Našli jste v článku chybu?

29. 3. 2003 13:36

Johanka (neregistrovaný)

Tyy vole tohle jsem nechala projit? Sypu si na hlavu tuny popela :)

29. 3. 2003 11:53

Yeti (neregistrovaný)

Jasně, pokud chci, aby ten patch zůstal patchem na 1.3, a nestal se patchem na HEAD, tak to je o něčem úplně jiném. OTOH to vzhledem k mizernému zacházení s větvemi v RCS (a CVS) většinou raději nechci ;-)

Podnikatel.cz: Změny v cestovních náhradách 2017

Změny v cestovních náhradách 2017

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

DigiZone.cz: TV Philips a Android verze 6.0

TV Philips a Android verze 6.0

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Měšec.cz: Jak levně odeslat balík přímo z domu?

Jak levně odeslat balík přímo z domu?

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Vitalia.cz: Potvrzeno: Pobyt v lese je skvělý na imunitu

Potvrzeno: Pobyt v lese je skvělý na imunitu

Podnikatel.cz: Snížení DPH na 15 % se netýká všech

Snížení DPH na 15 % se netýká všech

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Podnikatel.cz: Chaos u EET pokračuje. Jsou tu další návrhy

Chaos u EET pokračuje. Jsou tu další návrhy

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?