PHPPamokos.lt


8. Pakeitimų konfliktai ir jų sprendimo būdai

Pakartosiu klausimą, kurį uždaviau praeitos pamokos pabaigoje: kas bus, jei mes bandome parsisiųsti naujausią repozitorijos versiją su git pull, bet tuo metu jau patys buvome pakeitę tuos pačius failus? Kaip spręsti tokį konfliktą?

Parodysiu vaizdžiai, kaip tai atrodo - pradėkime eksperimentą. Jei pamenate iš praeitų pamokų, dabar jau turime du katalogus su tos pačios repozitorijos kopija - tarsi dirbame kaip komanda iš dviejų žmonių. Tai viename kataloge pakeiskime failą index.php ir įkelkime jį į GitHub:

Dabar pereikime prie mūsų pirminio katalogo ir ten taip pat pakeiskime index.php turinį. Ir pabandykime tada padaryti git pull - štai ką gausime:

Kaip matote, Git "keikiasi" ir sako, kad įvyko klaida: maždaug, jūs jau pakeitėte index.php failą ir reikia spręsti konfliktą.

Pirmiausia, ką reikia padaryti - apie ką mums sufleruoja ir pats Git - tai visus mūsų pakeitimus perkelti į lokalią repozitoriją - su git commit. Ir tada ir sena, ir nauja kodo versija bus vienoje repozitorijos vietoje, ir galėsime jas sulyginti ir pasirinkti, kurią versiją išsaugoti.

Matote, kad dabar status rodo, kad mes padarėme vieną pakeitimą, bet tuo pačiu ir atsiliekame vienu pakeitimu nuo parsiųstos repozitorijos. Kaip ir parašyta, darome dar kartą git pull:

Taigi, turime konfliktą, kurį turime išspręsti "rankiniu būdu" ir tada padaryti commit su jau teisinga failo index.php versija. Dabar pažiūrėkime į patį failą - būtent jame Git sistema atliko tam tikrus pakeitimus, kad mums parodytų, kur konfliktas:

Iš pirmo žvilgsnio, panika: prirašyta kažkokio dar kodo, kurio mes nerašėme! Bet iš tikro tai yra Git sistemos kodas, kuris mums palengvina konflikto sprendimo užduotį.

Viskas, kas yra tarp <<<<<<<<HEAD ir horizontalios linijos yra mūsų lokali failo kodo versija, o po linijos iki >>>>>>>> - iš repozitorijos.

Tai mūsų tikslas yra pasirinkti iš tų variantų ir ištrinti tuos Git simbolius. Sakykime, kad pasirinkome variantą su 2016 ir išsaugome index.php kaip tokį:

Ir paskutinis veiksmas - tą rezultatą įkelti į repozitoriją su commit ir push:

Viskas, konfliktas išspręstas, taigi apibendrinant - jei iškyla tokie nesklandumai dėl kodo versijų, jūs tiesiog atidarote tą failą, "išvalote" jį nuo Git kodo gabalų, paliekate teisingą kodo versiją ir įkeliate ją atgal į repozitoriją.


Konfliktai, sprendžiami automatiškai - auto-merge

Šitas konflikto variantas, kurį parodžiau pavyzdyje, iš tikro yra sudėtingas - yra ir paprastesnis. Kai to paties failo keičiama ne ta pati eilutė, o skirtingos - sakykime, vienas žmogus pakeitė vieną eilutę, o kitas kažką pakeitė visai kitoje eilutėje. Tokiu būdu Git pabandys sulyginti kodo versijas ir geriausią versiją išrinkti automatiškai - palikti abu pakeitimus. Pažiūrėkime, kaip tai veikia.

Dar "pažaiskime" su tuo pačiu index.php failu. Sakykime, kad situacija tokia, kad abiejuose mūsų kataloguose jis yra identiškas ir atrodo taip:

Iš katalogo Gitproject pakeiskime pirmąją eilutę ir įkelkime į GitHub:

Ir dabar padarykime tokį pakeitimą kitame kataloge - phppamokos/index.php:

Įkelkime šį pakeitimą į lokalią repozitoriją su git commit, ir tada pabandykime padaryti git pull - žiūrime kas gausis:

Štai taip - kaip ir minėjau, Git įvykdė auto-merge veiksmą sėkmingai: parašyta "Merge made by the 'recursive' strategy."

Taigi, didelė tikimybė, kad jeigu jūsų kolegos pakeis skirtingą kodo vietą negu jūs - tai Git visą "magiją" bandys padaryti už jus.

Tiek šioje pamokoje apie konfliktus ir jų sprendimą - toliau pratęsime pažintį su komanda merge, tik jau iš kitos pusės: kalbėsime apie atšakas ("branches").


(c) 2015-2018. Visais klausimais kreipkitės povilas@laraveldaily.com