Sloučit (správa verzí) - Merge (version control)

Příklad grafu historie projektu řízeného verzí se sloučením jako červené šipky

V řízení verzí je sloučení (také nazývané integrace) zásadní operací, která sladí více změn provedených ve sbírce souborů řízené verzemi. Nejčastěji je to nutné, když je soubor upraven na dvou nezávislých větvích a následně sloučen. Výsledkem je jediná kolekce souborů, která obsahuje obě sady změn.

V některých případech lze sloučení provést automaticky, protože existuje dostatek informací o historii k rekonstrukci změn a změny nejsou v konfliktu . V ostatních případech se člověk musí rozhodnout, co přesně by výsledné soubory měly obsahovat. Mnoho softwarových nástrojů pro řízení revizí obsahuje funkce sloučení.

Typy sloučení

Existují dva typy sloučení: automatické a ruční.

Automatické sloučení

Automatické sloučení je to, co software pro správu verzí provádí, když sladí změny, ke kterým došlo současně (v logickém smyslu). Také jiné části softwaru zavádějí automatické slučování, pokud umožňují úpravu stejného obsahu současně. Wikipedie například umožňuje dvěma lidem upravovat stejný článek současně; když druhý přispěvatel uloží, jejich změny se sloučí do článku místo přepsání předchozí sady změn.

Ruční sloučení

Manuální sloučení je to, k čemu se lidé musí uchýlit (případně mu pomáhají nástroje pro slučování), když musí sladit soubory, které se liší. Pokud například dva systémy mají mírně odlišné verze konfiguračního souboru a uživatel chce mít dobré věci v obou, lze toho obvykle dosáhnout ručním sloučením konfiguračních souborů a výběrem požadovaných změn z obou zdrojů (to je také nazývané obousměrné sloučení). Ruční sloučení je také vyžadováno, když automatické sloučení narazí na konflikt změn; například jen velmi málo nástrojů pro automatické sloučení může sloučit dvě změny na stejném řádku kódu (řekněme jednu, která změní název funkce, a druhou, která přidá komentář). V těchto případech se systémy řízení revizí uchýlí k uživateli, aby určil zamýšlený výsledek sloučení.

Sloučit algoritmy

Existuje mnoho různých přístupů k automatickému slučování, s jemnými rozdíly. Pozoruhodnější algoritmy sloučení zahrnují třícestné sloučení, rekurzivní třícestné sloučení, fuzzy patch aplikace, sloučení vazby a komutaci patchů.

Třícestné sloučení

Schéma třícestného sloučení
C je původ, A a B jsou deriváty C a D je nová výstupní verze

Po automatizované rozdílové analýze mezi souborem „A“ a souborem „B“ se provede třícestné sloučení, přičemž se vezme v úvahu také původ nebo společný předek obou souborů „C“. Je to hrubá metoda sloučení, ale široce použitelná, protože vyžaduje pouze jednoho společného předka k rekonstrukci změn, které mají být sloučeny.

Třícestné sloučení hledá části, které jsou stejné pouze ve dvou ze tří souborů. V tomto případě existují dvě verze oddílu a verze, která je ve společném předchůdci „C“, bude vyřazena, zatímco verze, která se liší, bude zachována ve výstupu. Pokud se „A“ a „B“ shodují, objeví se to ve výstupu. Sekce, která je stejná v „A“ a „C“, vydá změněnou verzi v „B“ a podobně sekce, která je stejná v „B“ a „C“, vydá verzi v „A“.

Sekce, které jsou ve všech třech souborech odlišné, jsou označeny jako konfliktní situace a ponechány na uživateli, aby je vyřešil.

Třícestné slučování je implementováno všudypřítomným programem diff3 a bylo hlavní inovací, která umožnila přechod ze systémů řízení revizí založených na zamykání souborů na systémy kontroly revizí založené na sloučení. Je široce používán systémem Concurrent Versions System (CVS).

Rekurzivní třícestné sloučení

Nástroje kontroly revizí založené na třícestném sloučení jsou rozšířené, ale tato technika zásadně závisí na nalezení společného předchůdce verzí, které mají být sloučeny.

Existují nepříjemné případy, zejména „křížové sloučení“, kdy jedinečný poslední společný předek upravených verzí neexistuje.

Problém „Criss-cross-merge“ v řízení verzí softwaru. V levé polovině jsou upravovány 2 oblasti a . a jsou postupně upravenými verzemi. Řešení je zobrazeno v pravé polovině: je vytvořen virtuální předek (přerušovaný kruh).

Naštěstí v tomto případě lze ukázat, že existují maximálně dva možní kandidátští předci a rekurzivní třícestné sloučení konstruuje virtuálního předka tak, že nejprve spojí nejedinečné předky. Toto sloučení může mít stejný problém, takže je algoritmus rekurzivně sloučí. Vzhledem k tomu, že v historii existuje konečný počet verzí, je zaručeno, že proces bude nakonec ukončen. Tuto techniku ​​používá nástroj pro kontrolu revizí Git .

(Implementace rekurzivního sloučení Git zvládá i další nepříjemné případy, jako je soubor upravovaný v jedné verzi a přejmenovaný v druhé, ale to jsou rozšíření jeho implementace třícestného sloučení; není součástí techniky pro hledání tří verzí ke sloučení.)

Rekurzivní třícestné sloučení lze použít pouze v situacích, kdy nástroj má znalosti o celkovém acyklickém grafu zaměřeném na původ (DAG) derivátů, které mají být sloučeny. V důsledku toho jej nelze použít v situacích, kdy deriváty nebo fúze plně neurčují své rodiče.

Fuzzy patch aplikace

Náplast je soubor, který obsahuje popis změn do souboru. Ve světě Unixu existuje tradice šíření změn v textových souborech jako patche ve formátu, který vytváří „ diff -u“. Tento formát pak může patch program použít k opětovnému použití (nebo odebrání) změn do (nebo z) textového souboru nebo adresářové struktury obsahující textové soubory.

Program patch má však také některá zařízení pro použití opravy do souboru, který není přesně podobný původnímu souboru, který byl použit k vytvoření opravy. Tento proces se nazývá fuzzy patch application a má za následek jakési asymetrické třícestné sloučení, kdy jsou změny v patchi zahozeny, pokud patch program nemůže najít místo, kde by je aplikoval.

Stejně jako CVS začínal jako sada skriptů na diff3 , GNU arch začínal jako sada skriptů na patch. Aplikace fuzzy patch je však relativně nedůvěryhodná metoda, někdy nesprávně aplikuje patche, které mají příliš malý kontext (zejména ty, které vytvářejí nový soubor), někdy odmítá použít delece, které provedly oba deriváty.

Patch komutace

Patch komutace se používá v Darcs ke sloučení změn a je také implementována v git (ale nazývá se „rebasing“). Sloučení komutace oprav znamená změnu pořadí oprav (tj. Popisů změn) tak, aby tvořily lineární historii. Ve skutečnosti, když jsou v rámci běžné situace vytvořeny dvě patche, při sloučení je jedna z nich přepsána, takže se zdá, že je provedena v kontextu druhé.

Komutace oprav vyžaduje, aby byly uloženy nebo mohly být rekonstruovány přesné změny, které vytvořily odvozené soubory. Z těchto přesných změn lze vypočítat, jak by měla být jedna z nich změněna, aby bylo možné ji na druhé rebase. Pokud například oprava A přidá řádek „X“ za řádek 7 souboru F a oprava B přidá řádek „Y“ za řádek 310 souboru F, musí být B přepsán, pokud je rebasován na A: řádek musí být přidán na řádek 311 souboru F, protože řádek přidaný do A kompenzuje čísla řádků o jednu.

Komutace záplat byla formálně hodně studována, ale algoritmy pro řešení konfliktů sloučení při komutaci oprav stále zůstávají otevřenými výzkumnými otázkami. Lze však prokázat, že komutace záplat vytváří „správné“ výsledky sloučení, kde jiné strategie sloučení jsou většinou heuristiky, které se snaží vytvořit to, co uživatelé chtějí vidět.

Flipdiff programu Unix z balíčku „patchutils“ implementuje komutaci patchů pro tradiční patche vytvořené programem diff -u.

Tkát splynout

Weave merge je algoritmus, který nevyužívá společného předka pro dva soubory. Místo toho sleduje, jak jsou přidávány a odstraňovány jednotlivé řádky v odvozených verzích souborů, a vytváří sloučený soubor s těmito informacemi.

Pro každý řádek v souborech derivátů shromažďuje sloučená vazba následující informace: které řádky předcházejí, které za ním následují a zda byl odstraněn v určité fázi historie derivátů. Pokud některý derivát v určitém bodě odstranil řádek, nesmí být ve sloučené verzi přítomen. U ostatních řádků musí být ve sloučené verzi přítomny.

Řádky jsou seřazeny do pořadí, kde je každý řádek za všemi řádky, které mu v určitém bodě historie předcházely, a před všemi řádky, které jej v určitém bodě historie následovaly. Pokud tato omezení nedávají celkové uspořádání pro všechny řádky, pak řádky, které nemají vzájemné řazení, jsou srážky, které jsou v konfliktu.

Weave merge byl zjevně používán komerčním nástrojem pro kontrolu revizí BitKeeper a dokáže zvládnout některé problémové případy, kdy třícestné sloučení produkuje špatné nebo špatné výsledky. Je to také jedna z možností sloučení nástroje pro kontrolu revizí GNU Bazaar a používá se v Codeville .

Viz také

Reference