Ako porozumieť a vyriešiť konflikty v Gite

Tam je slovo, ktoré nenávidí každý vývojár: konflikt. ? Pri práci so systémom Git (alebo inými systémami na správu verzií) občas nie je možné vylúčiť konflikt zlúčenia.

Ale keď hovorím s vývojármi, často počujem, že v súvislosti so zlúčením konfliktov existuje pocit úzkosti alebo nepohodlia .

Riešenie konfliktov často zostáva temným a záhadným miestom: situácia, keď sú veci vážne narušené a nie je jasné, ako sa z toho dostať (bez toho, aby sa situácia zhoršila).

Aj keď je pravda, že zlúčenie konfliktov je nevyhnutnou súčasťou života vývojára, nepohodlie v týchto situáciách je úplne voliteľné.

Mojím zámerom v tomto článku je objasniť túto tému: ako a kedy ku konfliktom zvyčajne dochádza, aké sú v skutočnosti a ako ich vyriešiť - alebo vrátiť späť.

Ak týmto veciam správne porozumiete, budete schopní riešiť konflikty pri zlúčení oveľa uvoľnenejšie a sebavedomejšie. ?

Ako a kedy dochádza ku konfliktom

Už názov to hovorí: „konflikty zlúčenia“ sa môžu vyskytnúť v procese integrácie záväzkov z iného zdroja.

Nezabudnite však, že „integrácia“ sa neobmedzuje iba na „zlučovanie pobočiek“. Môže sa to stať aj pri rebasingoch alebo interaktívnych rebasingoch, pri čerešničke alebo ťahu alebo dokonca pri opätovnom použití Stashu.

Všetky tieto činnosti vykonávajú určitý druh integrácie - a práve vtedy môže dôjsť ku konfliktom zlúčenia.

Ale samozrejme, tieto činy nemajú za následok zakaždým splynutie (vďakabohu!). V ideálnom prípade by ste sa v týchto situáciách mali ocitnúť iba zriedka. Kedy však presne dochádza ku konfliktom?

Schopnosti zlúčenia Git sú v skutočnosti jednou z jeho najväčších výhod: zlúčenie pobočiek funguje väčšinou bez námahy, pretože Git je zvyčajne schopný prísť na to sám.

Existujú však situácie, v ktorých došlo k rozporuplným zmenám - a kedy technológia jednoducho nemôže rozhodnúť, čo je správne alebo zlé. Tieto situácie si jednoducho vyžadujú rozhodnutie človeka.

Skutočná klasika je, keď bol úplne rovnaký riadok kódu zmenený v dvoch potvrdeniach na dvoch rôznych vetvách. Git nijako nevie, ktorej zmene dávate prednosť! ?

Existuje niekoľko ďalších podobných situácií - napríklad keď bol súbor upravený v jednej vetve a odstránený v inej - ale sú o niečo menej bežné.

Napríklad grafické rozhranie Git pre počítač „Tower“ má pekný spôsob vizualizácie týchto druhov situácií:

Ako vedieť, keď došlo ku konfliktu

Nerobte si starosti: Git vám veľmi jasne povie, kedy došlo ku konfliktu. ?  

Najprv vás okamžite upozorní na situáciu , napríklad keď dôjde ku konfliktu spojenia alebo rebázy:

$ git merge develop Auto-merging index.html CONFLICT (content): Merge conflict in index.html CONFLICT (modify/delete): error.html deleted in HEAD and modified in develop. Version develop of error.html left in tree. Automatic merge failed; fix conflicts and then commit the result.

Ako vidíte z vyššie uvedeného príkladu, keď som sa pokúsil vykonať zlúčenie, vytvoril som konflikt zlúčenia - a Git problém komunikuje veľmi jasne a pohotovo:

  • Došlo ku konfliktu v súbore „index.html“.
  • Došlo k ďalšiemu konfliktu v súbore „error.html“.
  • A nakoniec kvôli konfliktom zlyhala operácia zlúčenia.

To sú situácie, keď sa musíme prehrabať v kóde a zistiť, čo treba urobiť.

V nepravdepodobnom prípade, že ste tieto varovné správy prehliadli, keď došlo ku konfliktu, vás Git navyše informuje, kedykoľvek spustíte git status:

$ 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/rm ..." as appropriate to mark resolution) deleted by us: error.html both modified: index.html

Inými slovami: nebojte sa, že si nevšimnete konflikty pri zlučovaní. Git sa ubezpečuje, že ich nemôžete prehliadnuť.

Ako vrátiť konflikt v Gite a začať odznova

Zlúčenie konfliktov prichádza s určitou naliehavosťou. A oprávnene: budete sa s nimi musieť vysporiadať skôr, ako budete môcť pokračovať vo svojej práci.

Aj keď ich ignorovanie nie je možné, „riešenie konfliktov zlúčenia“ nemusí nutne znamenať, že ich musíte vyriešiť. Možné je aj ich zrušenie !

Toto by možno stálo za zopakovanie: vždy máte možnosť vrátiť späť konflikt zlúčenia a vrátiť sa do stavu predtým. Platí to, aj keď ste už začali riešiť konfliktné súbory a ocitli ste sa v slepej uličke.

V týchto situáciách je dobré mať na pamäti, že vždy môžete začať odznova a vrátiť sa do čistého stavu skôr, ako dôjde ku konfliktu.

Pre tento účel je väčšina príkazy prísť s --abortmožnosťou, napríklad git merge --abortaj git rebase --abort:

$ git merge --abort $ git status On branch main nothing to commit, working tree clean

To by vám malo dať istotu, že sa naozaj nemôžete pokaziť. Vždy môžete prerušiť tehotenstvo, vrátiť sa do čistého stavu a začať odznova.

Ako skutočne vyzerajú konflikty v Gite

Teraz, s vedomím, že sa nič nemôže zlomiť, pozrime sa, ako konflikt skutočne vyzerá pod kapotou. Toto demystifikuje tých malých bubákov a zároveň vám pomôže stratiť voči nim rešpekt a získať dôveru v seba.

Ako príklad sa pozrime na obsah (momentálne konfliktného) súboru „index.html“ v editore:

Git bol taký láskavý, že označil problémovú oblasť v súbore, uzavrel ju do <<<<<<< HEADa >>>>>>> [other/branch/name]. Obsah, ktorý nasleduje po prvej značke, pochádza z našej súčasnej pracovnej pobočky. Napokon riadok so =======znakmi oddeľuje dve protichodné zmeny.

Ako vyriešiť konflikt v Gite

Našou úlohou ako vývojárov je teraz vyčistiť tieto riadky: po dokončení musí súbor vyzerať presne tak, ako chceme.

Možno bude potrebné porozprávať sa so spoluhráčom, ktorý napísal „ostatné“ zmeny, a rozhodnúť, ktorý kód je v skutočnosti správny. Možno je to naše, možno je to ich - alebo možno zmes medzi týmito dvoma.

This process - cleaning up the file and making sure it contains what we actually want - doesn't have to involve any magic. You can do this simply by opening your text editor or IDE and starting to making your changes.

Often, however, you'll find that this is not the most efficient way. That's when dedicated tools can save time and effort:

  • Git GUI Tools: Some of the graphical user interfaces for Git can be helpful when solving conflicts. The Tower Git GUI, for example, offers a dedicated "Conflict Wizard" that helps visualize and solve the situation:
  • Dedicated Merge Tools: For more complicated conflicts, it can be great to have a dedicated "Diff & Merge Tool" at hand. You can configure your tool of choice using the "git config" command. (Consult your tool's documentation for detailed instructions.) Then, in case of a conflict, you can invoke it by simply typing git mergetool. As an example, here's a screenshot of "Kaleidoscope" on macOS:

After cleaning up the file - either manually or in a Git GUI or Merge Tool - we have to commit this like any other change:

  • By using git add on the (previously) conflicted file, we inform Git that the conflict has been solved.
  • When all conflicts have been solved and added to the Staging Area, you need to complete the resolution by creating a regular commit.

How to Become More Confident and Productive

Many years ago, when I started using version control, merge conflicts regularly freaked me out: I was afraid that, finally, I had managed to break things for good. ?

Only when I took the time to truly understand what was going on under the hood was I able to deal with conflicts confidently and efficiently.

The same was true, for example, when dealing with mistakes: only once I learned how to undo mistakes with Git was I able to become more confident and productive in my work.

I highly recommend taking a look at the free "First Aid Kit for Git", a collection of short videos about how to undo and recover from mistakes with Git.

Have fun becoming a better programmer!

About the Author

Tobias Günther je generálny riaditeľ spoločnosti Tower, populárneho desktopového klienta Git, ktorý pomáha viac ako 100 000 vývojárom po celom svete zvýšiť produktivitu práce s Gitom.