Přeskočit na hlavní obsah

Konflikty

S většinou běžných operací si Git umí poradit sám. Konflikt ovšem nastane, pokud je ve stejnou dobu upraven stejný obsah souboru. Vzniká při těchto operacích: pull, merge, rebase a cherry-pick. Nejlepší by bylo se konfliktům úplně vyhnout.

Jak se konfliktům vyhnout

Mějme příklad:

Ve své pracovní větvi upravíte stejnou funkci jako někdo jiný ve své větvi. Ten, kdo bude mergovat první, tomu merge projde v pořádku, nicméně tomu druhému nastane konflikt.

Upravujte pouze svoji oblast v rámci jedné větve!

Toto je klasický příklad toho, jak konflikty běžně vznikají. Přitom jim lze předcházet velmi snadno - prostě v rámci jedné větve upravte pouze svoji oblast. Pokud potřebujete upravit funkci, kterou ve své větvi používáte, ale přímo ji v rámci větve neupravujete.

Jak to tedy dělat správně?

Pokud potřebujete upravit oblast, která nepatří přímo do oblasti vaší větve, je mnohem čistější nejprve zkontrolovat, jestli neexistuje větev, která tuto oblast řeší. Pokud ne, tak tuto větev vytvořte a veškeré úpravy proveďte v ní.

Ano - na první pohled se jedná o složitější cestu k cíli. Nevyplatí se tento postup dělat, pokud víte, že jste jediný, kdo upravuje oblast. Ale pokud je riziko, že je na té oblasti někdo závislý, je vždy jednodušší udělat takový proces, než řešit následné konflikty.

Použijte rebase pro vyšší přehlednost

Tento ilustrační případ postupu používá metodu merge k aktualizaci pracovní větve. Proto graf vypadá tak složitě. Nicméně, lepší je použít rebase, který ale mění historii, a tak by nebyl vhodný pro tuto demonstraci. Výsledek pomocí rebase by vypadal takto:

Větev feature/gpio je v tuto dobu již mergnuta do mainu a smazána. Ostatní větve se posunuly na tento nový main, a tak to vypadá, že žádná zpětná úprava nebyla provedena.

Jak to vyřešit?

Řešení konfliktu je velmi nepříjemná činnost. V našem příkladu si ukážeme konflikt při:

git pull
Auto-merging src/main.py
CONFLICT (content): Merge conflict in src/main.py
Auto-merging docs/guide.md
CONFLICT (content): Merge conflict in docs/guide.md
Automatic merge failed; fix conflicts and then commit the result.

Pomocí git status si lze zobrazit soubory, ve kterých nastal konflikt.

git status
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)

Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/main.py
both modified: docs/guide.md

no changes added to commit (use "git add" and/or "git commit -a")

Nyní přichází ta nejvíce zmatečná část. Git automaticky do tvých souborů umístil tzv. konfliktní značky. Tyto značky vyhrazují konfliktní řádky. Mají následující význam:

  • Mezi <<<<<<< HEAD a ======= je tvoje verze.
  • Mezi ======= a >>>>>>> ... je druhá verze.
<<<<<<< HEAD
Moje (aktuální) verze řádků
=======
Jejich (přicházející) verze řádků
>>>>>>> jmeno-vetve-nebo-commit

Tyto značky musíš ručně odstranit a ponechat jen finální text. Uprav konfliktní soubory tak, jak chceš aby byly finálně. Soubory, u kterých dokončíš vyřešení konfliktu, standardně přidej pomocí příkazu git add.

Pokud konflikt nastal při pullu, je nutné vytvořit nový commit a ten standardně pushnout. V tomto případě nemusíte zadávat žádnou commit message, ta je automaticky vygenerována. Stačí zadat příkaz git commit.

Pokud konflikt nastal při merge, je postup stejný. Pokud ovšem nastal při rebase nebo cherry-pick, je nutné pokračovat v operaci. V takovém případě použijte příkaz git rebase --continue pro rebase a git cherry-pick --continue pro cherry-pick.

Výběr celých souborů

Pokud chcete vybrat celý soubor, nebo není možná ruční editace (např. u binárních jako jsou obrázky apod.), je možné nechat git použít celý soubor. Použijte příkaz git checkout --ours <file> pro výběr lokální verze souboru. Nebo příkaz git checkout --theirs <file> pro výběr verze ze serveru.

Grafické rozhraní

Git se dá používat bez problémů z příkazového řádku. Ve většině případů grafické prostředí nepřináší příliš velkou přidanou hodnotu. U řešení konfliktů je ale situace jiná. Většina grafických rozhraní vám totiž velmi efektivně ukáže změny na jednotlivých řádcích. A vy můžete velmi přehledně vybrat, kterou verzi chcete zachovat.

Ukázka je z prostředí Pycharm