9. diel - Git - Kolízia medzi vetvami
V predchádzajúcom kvíze, Kvíz - Skúmanie histórie, správa a zlučovanie vetiev v Gitu, sme si overili nadobudnuté skúsenosti z predchádzajúcich lekcií.
V dnešnom Git tutoriále sa budeme zaoberať kolíziami pri zlučovaní vetiev. Vysvetlíme si, kedy kolízie vznikajú. Na praktickom príklade sa naučíme, ako kolíziu najlepšie vyriešiť.
Všetky príkazy budeme vykonávať v našom naklonovanom
repositári Laravel z lekcie Git – Základy –
Dokončenie. Otvoríme terminál MinTTY
a pomocou príkazu
cd laravel
sa do repositára presunieme.
Kolízie medzi vetvami
Kolízie vznikajú pri zlučovaní dvoch vetiev. Kolízia nastane, keď sa dve vetvy súčasne pokúšajú upraviť rovnakú časť kódu alebo súbor a Git nedokáže rozhodnúť, ktorú verziu použiť.
Kolízie môžu vzniknúť z nasledujúcich dôvodov:
- úpravy rovnakého riadku kódu,
- zmazanie alebo premenovanie súborov,
- zmeny v rôznych častiach rovnakého súboru.
Ak dôjde ku kolízii, Git označí súbory, v ktorých sa konflikt vyskytol.
Súbory sú označené ako nevyriešené zmeny alebo
unmerged paths
. V takom prípade je na vývojári, aby konflikt
vyriešil a určil, ktoré zmeny majú byť zachované.
Riešenie kolízií je dôležitou súčasťou správy verzií v Gitu a je
nevyhnutné pre koordináciu vývoja projektu v tíme.
Ak by sme narazili na kolíziu pri zlučovaní, spustením príkazu
git status
by sme si zobrazili výpis súborov, ktoré kolíziu
spôsobili. Ak by napríklad obe naše vetvy upravili rovnakú časť súboru
README.md
, zobrazila by sa táto varovná správa:
On branch 10.x Unmerged paths: (use "git add/rm ..." as appropriate to mark resolution) both modified: README.md
Typy kolízií
Konflikty môžu nastať v dvoch prípadoch: na začiatku procesu zlúčenia alebo počas neho.
Zlyhanie zlúčenia pri spustení
Tento typ kolízie nastáva v prípade, keď by boli prebiehajúce zmeny v
pracovnom adresári alebo v pracovnej oblasti projektu prepísané commity,
ktoré sa práve zlučujú. Tento problém vzniká kvôli existujúcim lokálnym
zmenám. Na odstránenie tejto situácie a prevzatie kontroly nad miestnym
stavom slúžia príkazy git checkout
, git commit
a
git reset
.
Pri zlyhaní zlúčenia pri spustení sa zobrazí nasledujúca správa:
error: Entry '<fileName>' not uptodate. Cannot merge. (Changes in working directory)
Zlyhanie počas zlučovania
Kolízia typu zlyhania počas zlučovania hovorí, že došlo ku konfliktu medzi aktuálnou cieľovou vetvou a zlučovanou vetvou. Pri tomto type kolízie sa zobrazí nasledujúca správa:
error: Entry '<fileName>' would be overwritten by merge. Cannot merge. (Changes in staging area)
Identifikácia konfliktov pri zlučovaní vetiev
Na nasledujúcom príklade si ukážeme, ako taká kolízia môže vzniknúť. Naučíme sa miesto kolízie identifikovať a opraviť.
Začneme tým, že sa prepneme do vetvy feature
:
MINGW64:/c/mygit/laravel IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x) $ git checkout feature IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (feature) $
Vetva feature
sme zakladali v lekcii Git - Zlučovanie
vetiev. Pokiaľ ju nemáte, založte si ju príkazom
git checkout -b feature
.
Teraz vykonáme editáciu súboru README.md
a vytvoríme
commit:
MINGW64:/c/mygit/laravel IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (feature) $ echo "Editing a file on the feature branch" >> README.md IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (feature) $ git add README.md IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (feature) $ git commit -m "Modification of README.md file" [feature 59424c6f] Modification of README.md file 1 file changed, 1 insertion(+) IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (feature) $
Nasledovne sa prepneme na vetvu 10.x
, vykonáme editáciu
súboru README.md
a vytvoríme commit:
MINGW64:/c/mygit/laravel IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (feature) $ git checkout 10.x IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x) $ echo "Editing a file on the 10.x branch" >> README.md IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x) $ git add README.md IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x) $ git commit -m "Modification of README.md file" [10.x 875436f6] Modification of README.md file 1 file changed, 1 insertion(+) IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x) $
V poslednom kroku zlúčime vetvu feature
s vetvou
10.x
:
MINGW64:/c/mygit/laravel IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x) $ git merge feature Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result. IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x|MERGING) $
Hlásenie o kolízii
Po spustení príkazu git merge
nastane kolízia a vypíše sa
nám nasledujúca správa:
Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.
Správa nám oznamuje, že došlo ku kolízii v súbore
README.md
a automatické zlúčenie zlyhalo. Teraz sa pozrieme na
nezlúčené vetvy. Spustite príkaz git status
, aby sme získali
nasledujúci výpis o stave repositára:
MINGW64:/c/mygit/laravel IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x|MERGING) $ git status On branch 10.x Your branch is ahead of 'origin/10.x' by 5 commits. (use "git push" to publish your local commits) 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: README.md no changes added to commit (use "git add" and/or "git commit -a") IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x|MERGING) $
Výpis nám hovorí:
On branch 10.x
- Nachádzame sa na vetve10.x
Your branch is ahead of 'origin/10.x' by 5 commits.
- Lokálna vetva má o 5 commitov viac ako vzdialená vetvaorigin/10.x
.You have unmerged paths.
- Existujú súbory, ktoré nemožno automaticky zlúčiť. Konflikty v týchto súboroch je potrebné vyriešiť ručne.Unmerged paths:
- Existujú súbory so zmenami, ktoré treba ručne zlúčiť.both modified: README.md
- SúborREADME.md
bol upravený oboma vetvami a spôsobil kolíziu.
Vidíme, že súbor README.md
spôsobil kolíziu. Keďže
cieľová a zlučovaná vetva obsahujú zmeny, Git nevie, akú verziu súboru
použiť, a preto vyvolal kolíziu.
Nájdenie miesta kolízie
Miesto, kde došlo ku kolízii, si popíšeme. Otvoríme súbor
README.md
príkazom cat
:
MINGW64:/c/mygit/laravel IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x|MERGING) $ cat README.md ...
Miesto, kde došlo ku kolízii pri zlúčení, je označené týmito vizuálnymi znakmi:
<<<<<<< HEAD Editing a file on the 10.x branch ======= Editing a file on the feature branch >>>>>>> feature
Značky =======
označujú stred kolízie. Obsah medzi týmito
značkami a riadkom HEAD
predstavuje obsah existujúci v aktuálnej
cieľovej vetve, na ktorý odkazuje ukazovateľ HEAD
.
Riešenie kolízie
Pokiaľ sa stretneme s kolíziou, je dôležité ju správne vyriešiť. Najbežnejším postupom je upraviť súbor, v ktorom ku kolízii došlo, a určiť, ktoré zmeny majú byť zachované.
V našom prípade sa bude jednať o súbor README.md
. Otvoríme
ho v editore a nájdeme nasledujúce konfliktné značky:
MINGW64:/c/mygit/laravel ... Added text 1 Added text 2 <<<<<<< HEAD Editing a file on the 10.x branch ======= Editing a file on the feature branch >>>>>>> feature
Pre vyriešenie kolízie je nutné odstrániť konfliktné značky a upraviť
obsah tak, aby zodpovedal požadovanému výsledku zlúčenia. Súbor
README.md
upravíme tak, aby boli prítomné úpravy z oboch
vetiev. Koniec súboru README.md
bude vyzerať nasledovne:
... Added text 1 Added text 2 Editing a file on the 10.x branch Editing a file on the feature branch
Upravený súbor uložíme a vykonáme commit pre uloženie vykonaných zmien:
MINGW64:/c/mygit/laravel IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x|MERGING) $ git add . IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x|MERGING) $ git commit -m "Fixing a merge conflict between branches" [10.x 139dc808] Fixing a merge conflict between branches IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x) $
Po vytvorení commitu je kolízia úspešne vyriešená a zmeny sú zaznamenané v repositári. Zlúčenie vetiev sa automaticky dokončí po vytvorení commitu.
V budúcej lekcii, Git - Vzdialený repositár - GitHub a protokoly HTTPS a SSH, si založíme profil na GitHube. Ukážeme si, ako nastaviť Git na pripojenie cez protokoly HTTPS a SSH.