Sloučit nebo mergovat — je operace spojení dvou větví v Git, která sjednocuje změny z jedné větve do druhé. V moderním vývoji je merge standardní způsob integrace feature větve do hlavní větve projektu. Podle GitHub Octoverse 2024 se denně provádí více než 15 milionů mergů. Merge — klíčový mechanismus kolaborativní práce, který umožňuje sjednotit práci několika vývojářů do jednoho produktu.
Hlavní body
Merge v Git — je operace spojení dvou nebo více historií vývoje do jedné. Když vývojář sloučí větev, Git automaticky najde společného předka (base commit) a vytvoří nový merge commit, který zahrnuje změny z obou větví. Three-way merge — standardní algoritmus porovnávající tři stavy: společného předka, první větev a druhou větev.
Proces mergování začíná příkazem git merge. Git určí bod rozdělení větví a sekvenčně aplikuje změny z zdrojové větve na cílovou. Pokud změny nejsou v konfliktu, Git provede fast-forward nebo vytvoří merge commit v závislosti na nastavení. Fast-forward — scénář, kdy se cílová větev jednoduše posune na commity zdrojové větve.
# Přepni na cílovou větev a slouč
git checkout main
git merge feature/payment-module
# Slouč s explicitním no-fast-forward
git merge --no-ff feature/payment-module
# Přeruš sloučení, pokud jsou konflikty příliš složité
git merge --abort
Příznak --no-ff (no fast-forward) vynucuje vytvoření merge commit i když je fast-forward možný. To zachovává informaci, že změny byly provedeny v samostatné větvi. Mnoho týmů preferuje právě tento přístup pro zachování větvení historie v explicitní podobě.
V Git existují tři hlavní strategie sloučení větví, každá vhodná pro určitý scénář. Volba strategie závisí na kultuře týmu a požadavcích na čistotu historie projektu.
| Strategie | Výsledek | Kdy použít |
|---|---|---|
| Standard merge | merge commit + celá historie | týmy, které si cení úplné historie |
| Squash merge | jeden commit, historie komprimovaná | feature větve s mnoha malými commity |
| Rebase merge | lineární historie, bez merge commit | osobní feature větve, před vytvořením PR |
Standard merge vytvoří merge commit se dvěma rodiči. Celá historie je zachována, ale graf větvení se stává složitějším. Squash merge spojí všechny commity feature větve do jednoho a aplikuje jej na cílovou větev — historie se stává lineární a čistou, ale ztrácí se informace o mezistupních.
Rebase, i když není plnohodnotným mergem, dosahuje stejného výsledku — změny z jedné větve jsou přeneseny na druhou. Rozdíl je v tom, že historie je přepisována: commity feature větve jsou znovu vytvořeny nad posledním commitem cílové větve. To dává ideálně lineární historii, ale vyžaduje force push při odesílání.
Konflikt při mergování nastává, když jsou ve dvou větvích změněny stejné řádky souboru. Git nemůže automaticky určit, kterou verzi zachovat, a vyžaduje zásah vývojáře. Konflikty jsou v souborech zobrazeny jako speciální značky: <<<<<<<, =======, >>>>>>>.
Proces řešení konfliktu zahrnuje několik kroků. Nejprve vývojář otevře konfliktní soubor a ručně vybere potřebné změny. Je důležité nevybrat jen jednu z verzí, ale pochopit logiku obou změn a učinit správné rozhodnutí. Po úpravě souboru jsou značky konfliktu odstraněny a změny jsou přidány do staging area pomocí git add.
# Zobraz seznam konfliktních souborů
git status
# Spusť mergetool (např. VS Code, IntelliJ)
git mergetool
# Po vyřešení všech konfliktů
git add .
git merge --continue
# Nebo sloučení zcela zruš
git merge --abort
Použití vizuálních nástrojů pro merge výrazně urychluje řešení konfliktů. VS Code, IntelliJ IDEA a GitKraken poskytují rozhraní se třemi panely: aktuální větev, příchozí větev a výsledek. Nástroj git mergetool automaticky otevře nakonfigurovaný editor pro každý konfliktní soubor.
Nejlepším způsobem, jak se vyhnout složitým konfliktům, je pravidelná synchronizace feature větve s hlavní větví. Pokud vývojář sloučí main do své větve jednou denně, konflikty budou malé a snadno řešitelné. Hromadění změn po dobu týdne zaručuje složité konflikty s vysokým rizikem chyb.
Rebase a merge — dva způsoby kombinování změn a volba mezi nimi často vyvolává debaty v týmech. Rebase přesouvá commity z jedné větve na druhou a přepisuje historii. Merge vytváří nový merge commit a zachovává historii větvení. Každý přístup má své výhody a omezení.
Rebase je vhodný, když vývojář pracuje ve své lokální feature větvi a chce získat čistou lineární historii před vytvořením Pull Request. Po rebase jsou všechny commity seřazeny sekvenčně bez zbytečných merge commit. Nicméně rebase vyžaduje force push a není použitelný na větvích, na kterých pracuje několik lidí současně.
Zlaté pravidlo Git: nepoužívejte rebase na commitech, které již byly odeslány do sdíleného repozitáře. To zaručuje, že historie ve společné větvi zůstává nezměněna a ostatní vývojáři nenarazí na duplicitní nebo ztracené commity. Pro integraci feature větve do hlavní větve použijte merge přes Pull Request.
Správný proces mergování — základ stabilního vývoje. V moderní týmové práci se merge provádí ne přes konzoli, ale přes Pull Request na GitHub nebo Merge Request v GitLab. PR prochází code review, automatickými CI kontrolami a teprve poté je sloučen do hlavní větve.
První praxe — mergujte až po absolvování všech kontrol. CI pipeline musí sestavit projekt, spustit testy a zkontrolovat kvalitu kódu. Pokud alespoň jedna kontrola neprošla, merge je blokován. Moderní platformy (GitHub, GitLab) mají vestavěnou ochranu: branch protection rules automaticky blokují merge při pádu CI.
Druhá praxe — nikdy nemergujte rozbitý kód. Před mergem se vývojář musí ujistit, že jeho změny nerozbíjejí build a neregresují stávající funkcionalitu. K tomu slouží automatické testy a code review.
Třetí praxe — čistěte feature větve po mergi. Větev, která již byla sloučena, musí být smazána. To zabraňuje zmatkům a zaneřádění repozitáře. GitHub automaticky nabízí smazání větve po mergi PR a nastavení repozitáře lze nakonfigurovat pro automatické mazání.
Často kladené otázky
Merge — sloučení dvou Git větví do jedné. Změny z jedné větve jsou přeneseny do druhé prostřednictvím trojcestného sloučení (three-way merge). Výsledek je zaznamenán v novém merge commitu, který má dva rodičovské commity. Merge commit uchovává informaci o tom, které větve byly sloučeny.
Merge vytváří nový merge commit a zachovává historii větvení. Rebase přepisuje historii přesouváním commitů na jinou větev bez vytvoření merge commit. Rebase poskytuje lineární historii, ale vyžaduje force push. Merge je bezpečnější pro společné větve, rebase je lepší pro osobní.
Otevřete konfliktní soubor, najděte značky <<<<<<<, ======= a >>>>>>>, vyberte požadované změny a odstraňte značky. Přidejte soubor pomocí git add a dokončete merge příkazem git merge --continue. Použijte git mergetool pro vizuální řešení ve VS Code nebo IntelliJ IDEA.
Pull Request (nebo Merge Request) je povinný při sloučení feature větve do hlavní větve projektu. PR prochází code review kolegů a automatickými CI kontrolami. To je standard moderního vývoje. Přímý push do main větve je ve většině projektů zakázán.
Squash merge spojí všechny commity feature větve do jednoho před sloučením. To poskytuje čistou historii hlavní větve bez mezilehlých pracovních commitů. Použijte squash merge, když feature větev obsahuje mnoho servisních commitů (wip, fixes) a není potřeba uchovávat všechny mezilehlé kroky v historii.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také