Kuidas Gitis konflikte mõista ja lahendada

Seal on see sõna, mida iga arendaja vihkab näha: konflikt. ? Gitiga (või mõne muu versiooni juhtimissüsteemiga) töötades pole lihtsalt võimalik vältida juhuslikke ühenduskonflikte.

Kuid arendajatega rääkides kuulen sageli, et konfliktide liitmise teema ümber on tunda ärevust või ebamugavust .

Konfliktide käsitlemine jääb sageli pimedaks, salapäraseks kohaks: olukord, kus asjad on halvasti katki ja pole selge, kuidas sellest välja tulla (ilma et see veelgi hullemaks muutuks).

Kuigi on tõsi, et ühinemiskonfliktid on arendaja elu vältimatu osa, on ebamugavus nendes olukordades täiesti vabatahtlik.

Minu eesmärk on selle artikliga tuua selles teemas veidi selgust: kuidas ja millal konfliktid tavaliselt tekivad, millised need tegelikult on ja kuidas neid lahendada - või tagasi võtta.

Kui saate neist asjadest õigesti aru, saate konfliktide lahendamisel palju pingevabamalt ja enesekindlamalt hakkama saada. ?

Kuidas ja millal konfliktid tekivad

Nimi ütleb seda juba: teisest allikast pärinevate toimingute integreerimise käigus võivad tekkida "ühenduskonfliktid".

Pidage siiski meeles, et "integreerimine" ei piirdu ainult "filiaalide ühendamisega". See võib juhtuda ka uuesti või interaktiivse taaskäivitamise ajal, kirsside valimise või tõmbe sooritamisel või isegi Stashi uuesti rakendamisel.

Kõik need toimingud viivad läbi mingisuguse integratsiooni - ja siis võivad juhtuda ühenduskonfliktid.

Kuid loomulikult ei põhjusta need toimingud iga kord ühenduskonflikti (jumal tänatud!). Ideaalis peaksite sellistes olukordades sattuma vaid harva. Aga millal täpselt konfliktid tekivad?

Tegelikult on Giti ühendamisvõimalused üks selle suurimaid eeliseid: harude ühendamine töötab enamasti pingutuseta, sest Git suudab tavaliselt asjad ise selgeks saada.

Kuid on olukordi, kus tehti vastuolulisi muudatusi - ja kus tehnoloogia lihtsalt ei suuda otsustada, mis on õige või vale. Need olukorrad nõuavad inimeselt lihtsalt otsust.

Tõeline klassika on see, kui täpselt sama koodirida muudeti kahes toimingus kahel erineval harul. Gitil pole võimalust teada saada, millist muudatust eelistate! ?

On veel mõningaid sarnaseid olukordi - näiteks kui faili muudeti ühes harus ja kustutati teises -, kuid need on natuke vähem levinud.

Näiteks "Tower" Giti töölaua GUI- l on kena viis visualiseerida selliseid olukordi:

Kuidas teada saada, kui on tekkinud konflikt

Ärge muretsege: Git ütleb teile väga selgelt, kui konflikt on juhtunud. ?  

Esiteks annab see teile olukorras viivitamatult teada , näiteks kui ühendamine või uuestibaasimine konflikti tõttu nurjub:

$ 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.

Nagu ülaltoodud näitest näha, lõin ühendamise ajal proovides ühenduskonflikti - ja Git edastab probleemi väga selgelt ja kiiresti:

  • Failis "index.html" tekkis konflikt.
  • Tekkis veel üks konflikt failis "error.html".
  • Ja lõpuks nurjus konfliktide tõttu ühinemisoperatsioon.

Need on olukorrad, kus peame süvenema koodi ja vaatama, mida tuleb teha.

Ebatõenäolisel juhul, kui olete konflikti tekkides need hoiatussõnumid kahe silma vahele jätnud, teavitab Git teid täiendavalt alati, kui käivitate 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

Teisisõnu: ärge muretsege ühenduste konfliktide märkamata jätmise pärast. Git hoolitseb selle eest, et te ei saaks neist mööda vaadata.

Kuidas Gitis konflikt tühistada ja otsast alustada

Ühenduskonfliktid kaasnevad teatava kiireloomulisusega. Ja õigustatult: enne kui saate oma tööd jätkata, peate nendega tegelema.

Ehkki nende ignoreerimine pole valikuvõimalus, ei tähenda "ühenduskonfliktide lahendamine" tingimata seda, et peate need lahendama. Nende tagasivõtmine on samuti võimalik!

Seda tasub ehk korrata: teil on alati võimalus ühenduskonflikt tühistada ja naasta varasemasse olekusse. See kehtib isegi siis, kui olete juba konfliktseid faile lahendama hakanud ja sattunud tupikusse.

Nendes olukordades on suurepärane meeles pidada, et võite alati alustada otsast ja naasta puhtasse olukorda enne, kui konflikt üldse aset leidis.

Selleks, kõige käsud tulevad koos --abortvõimalus, näiteks git merge --abortja git rebase --abort:

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

See peaks andma teile enesekindluse, et te ei saa tegelikult sassi minna. Alati saate katkestada, naasta puhtasse olekusse ja alustada otsast peale.

Kuidas konfliktid Gitis tegelikult välja näevad

Nüüd, olles teadlik, et miski ei saa puruneda, vaatame, kuidas konflikt kapoti all tegelikult välja näeb . See demüstifitseerib neid väikeseid lollakaid ja aitab samal ajal kaotada austust nende vastu ning saavutada enesekindlust.

Näiteks vaatame redaktoris (praegu konfliktset) faili "index.html" sisu:

Git oli lahke, et märkida faili probleemse ala, lisades selle <<<<<<< HEADja >>>>>>> [other/branch/name]. Pärast esimest markerit pärinev sisu pärineb meie praegusest tööharust. Lõpuks =======eraldab tähemärkidega rida kaks vastuolulist muudatust.

Kuidas Gitis konflikti lahendada

Meie ülesanne arendajatena on nüüd nende ridade puhastamine: pärast lõpetamist peab fail välja nägema täpselt nii, nagu me tahame.

Võib-olla on vaja rääkida meeskonnakaaslasega, kes kirjutas "muud" muudatused, ja otsustada, milline kood on tegelikult õige. Võib-olla on see meie, võib-olla nende oma - või võib-olla nende kahe segu.

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 on torni tegevdirektor, populaarne Giti töölauaklient, mis aitab enam kui 100 000 arendajal üle kogu maailma Gitiga produktiivsemalt töötada.