Kā saprast un risināt konfliktus Gitā

Tur tas ir vārds, kuru ienīst redzēt katrs izstrādātājs: konflikts. ? Vienkārši nav iespējams izvairīties no gadījuma rakstura apvienošanās konflikta, strādājot ar Git (vai citām versiju kontroles sistēmām).

Bet, runājot ar izstrādātājiem, es bieži dzirdu, ka konfliktu apvienošanas tēma ir saistīta ar trauksmi vai diskomfortu .

Konfliktu risināšana bieži paliek tumša, noslēpumaina vieta: situācija, kad lietas ir ļoti salauztas un nav skaidrs, kā no tās izkļūt (nepasliktinot lietas).

Lai gan taisnība, ka apvienošanās konflikti ir neizbēgama izstrādātāja dzīves sastāvdaļa, diskomforts šajās situācijās nav obligāts.

Mans nolūks ar šo rakstu ir ieviest zināmu skaidrību šajā tēmā: kā un kad parasti notiek konflikti, kādi tie patiesībā ir un kā tos atrisināt vai atsaukt.

Pareizi izprotot šīs lietas, jūs varēsiet daudz vieglāk un pārliecinātāk risināt konfliktu apvienošanu. ?

Kā un kad notiek konflikti

Nosaukums jau saka: “apvienot konfliktus” var rasties no cita avota veiktu saistību integrēšanas procesā.

Tomēr paturiet prātā, ka "integrācija" neaprobežojas tikai ar "filiāļu apvienošanu". Tas var notikt arī tad, kad veicat atkārtotu vai interaktīvu atkārtotu novērtēšanu, veicot ķiršu izvēli vai vilkšanu vai pat atkārtoti lietojot atlicināt.

Visas šīs darbības veic kaut kādu integrāciju - un tieši tad var notikt apvienošanās konflikti.

Bet, protams, šīs darbības katru reizi neizraisa saplūšanas konfliktu (paldies Dievam!). Ideālā gadījumā jums vajadzētu nonākt šajās situācijās tikai reti. Bet kad tieši notiek konflikti?

Faktiski Git apvienošanas iespējas ir viena no tās lielākajām priekšrocībām: filiāļu apvienošana lielāko daļu laika darbojas bez piepūles, jo Git parasti spēj pats izdomāt lietas.

Bet ir situācijas, kad tika veiktas pretrunīgas izmaiņas - un kur tehnoloģija vienkārši nevar izlemt, kas ir pareizi vai nepareizi. Šīs situācijas vienkārši prasa cilvēka lēmumu.

Patiesā klasika ir tad, kad precīzi viena un tā pati koda rinda tika mainīta divās saistībās, divās dažādās nozarēs. Gitam nav iespējas uzzināt, kurām izmaiņām dodat priekšroku! ?

Ir dažas citas, līdzīgas situācijas - piemēram, kad fails tika pārveidots vienā filiālē un izdzēsts citā -, bet tie ir nedaudz retāk sastopami.

Piemēram, "Tower" Git darbvirsmas GUI ir jauks veids, kā vizualizēt šāda veida situācijas:

Kā uzzināt, kad noticis konflikts

Neuztraucieties: Gits jums ļoti skaidri pateiks, kad noticis konflikts. ?  

Pirmkārt, tas nekavējoties informēs jūs situācijā , piemēram, ja apvienošana vai atkārtota bāze neizdodas konflikta dēļ:

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

Kā redzat no iepriekš minētā piemēra, mēģinot veikt sapludināšanu, es izveidoju apvienošanās konfliktu - un Gits problēmu skaidri un ātri paziņo:

  • Radās konflikts failā "index.html".
  • Radās vēl viens konflikts failā "error.html".
  • Un visbeidzot, konfliktu dēļ apvienošanās darbība neizdevās.

Šīs ir situācijas, kad mums ir jāiedziļinās kodā un jāskatās, kas jādara.

Maz ticams, ka konflikta laikā esat aizmirsis šos brīdinājuma ziņojumus, Git jūs papildus informē par katru palaišanu 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

Citiem vārdiem sakot: neuztraucieties, ka nepamana sapludināšanas konfliktus. Gits pārliecinās, ka jūs nevarat tos nepamanīt.

Kā atsaukt Git konfliktu un sākt no jauna

Apvienošanās konflikti rodas ar zināmu steidzamību. Un tas ir pareizi: jums būs jārisina ar viņiem, pirms jūs varat turpināt savu darbu.

Lai gan to ignorēšana nav risinājums, "apvienošanās konfliktu risināšana" ne vienmēr nozīmē, ka jums tie ir jāatrisina. Iespējams arī tos atsaukt !

Tas varētu būt vērts atkārtot: jums vienmēr ir iespēja atsaukt apvienošanās konfliktu un atgriezties iepriekšējā stāvoklī. Tas notiek pat tad, kad esat jau sācis risināt konfliktējošos failus un nonākat strupceļā.

Šādās situācijās ir lieliski paturēt prātā, ka jūs vienmēr varat sākt no jauna un atgriezties tīrā stāvoklī, pirms konflikts pat noticis.

Šim nolūkam, lielākā daļa komandas nāk ar --abortiespēju, piemēram, git merge --abortun git rebase --abort:

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

Tam vajadzētu dot pārliecību, ka jūs patiešām nevarat sajaukt. Jūs vienmēr varat pārtraukt darbu, atgriezties tīrā stāvoklī un sākt no jauna.

Kā konflikti patiesībā izskatās Gitā

Tagad, droši zinot, ka nekas nevar izlauzties, redzēsim, kāds konflikts patiesībā izskatās zem pārsega. Tas demistificēs šos mazos blēžus un vienlaikus palīdzēs jums zaudēt cieņu pret viņiem un iegūt pārliecību par sevi.

Apskatīsim redaktorā (pašlaik konfliktējošā) faila "index.html" saturu:

Gits bija pietiekami laipns, lai failā atzīmētu problēmu zonu, pievienojot to <<<<<<< HEADun >>>>>>> [other/branch/name]. Saturs, kas nāk pēc pirmā marķiera, nāk no mūsu pašreizējās darba nozares. Visbeidzot, rinda ar =======rakstzīmēm atdala abas konfliktējošās izmaiņas.

Kā atrisināt konfliktu Gitā

Mūsu kā izstrādātāju uzdevums tagad ir attīrīt šīs rindas: pēc tam, kad mēs esam pabeiguši, failam ir jāizskatās tieši tā, kā mēs to vēlamies.

Var būt nepieciešams runāt ar komandas biedru, kurš uzrakstīja izmaiņas “citas”, un izlemt, kurš kods ir pareizs. Varbūt tas ir mūsu, varbūt tas ir viņu - vai varbūt abu sajaukums.

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

Tobiass Ginters ir Tower, populārā Git darbvirsmas klienta, izpilddirektors, kas palīdz vairāk nekā 100 000 izstrādātājiem visā pasaulē būt produktīvākiem ar Git.