Tiimityö versionhallinnassa

Ohjelmistokehityksessä jokainen tiimin jäsen tekee kehitystyötä paikallisessa tietovarastossaan, joka sisältää etätietovaraston jonkin ajanhetken sisällön. Kun työ on valmis, ja toimivaksi testattu, valmis koodi synkronoidaan osaksi kokonaisuutta lisäämällä ne yhteisesti jaettuun etätietovarastoon. Niin kauan, kun työskentelee oman koodinsa parissa paikallisesti, muiden tekemät muutokset eivät vaikuta tekemiseen. Kaikkien muutokset tulevat näkyviin, kun

  1. paikallisesta tietovarastosta on siirretty tiedot etätietovarastoon

  2. paikallinen tietovarasto on päivitetty etätietovaraston uuteen sisältöön

Kun useita henkilöitä työskentelee samassa tietovarastossa, on myös riski sille, että useampi henkilö muokkaa jollain tavalla (editoi tai poistaa) samaan aikaan samoja tiedostoja, jolloin syntyy konflikti.

Tyypillinen konfliktitilanne on esitettynä alla olevassa kuvassa. Siinä kahdessa erillisessä, paikallisessa tietovarastossa on molemmissa tehty uudet commitit D1 ja D2, joita edeltää commit C, joka löytyy etätietovarastosta. Ensimmäinen commitinsa etätietovarastoon työntävä onnistuu pushissa ongelmitta. Etätietovarastoon lisätään D1-commit ja haara päivitetään osoittamaan tähän uuteen committiin aivan normaalisti. Ongelmia syntyy, kun toinen tiimiläinen yrittää työntää oman koodinsa samaan etätietovarastoon.

Etätietovaraston mielestä haaran pää on D1-commitissa ja toisen käyttäjän tietovaraston mielestä D2-commitissa. Versionhallinta ei voi tietää, kuummalla käyttäjällä on oikea versio, jolloin oletuksena Git estää operaation ja pakottaa käyttäjän ratkomaan ongelman itse.

../../_images/gvc_one_branch_conflict.png

Versiokonflikti (kuva Git-kurssilta)

Tilanteeseen on käytännössä useita erilaista ratkaisuja, joista mikään ei ole varmasti toista parempi. Esimerkiksi:

  1. Commitit voidaan yhdistää.

  2. Commiteistä voidaan hylätä D2.

  3. Voidaan lisätä D2 ja pakottaa haara osoittamaan siihen eli hylätä D1.

  4. Molemmat Commitit voivat toimia uuden kehityspolun alkuna.

  5. D2:n aloituskohtaa voidaan muuttaa.

Git ei voi automaattisesti päättää toimintatapaa käyttäjän puolesta.

Varoitus!

Älä käytä –force -vipua, jos push epäonnistuu

Force-vivulla käytännössä tehdään ratkaisu, jossa D2:lla korvataan D1.

Jos et tiedä tarkalleen ja punnitusti, mitä olet tekemässä saatat:

  1. Tuhota toisen työt.

  2. Korvata ehjän versiohistorian korruptoituneella.

  3. Pahimmassa tapauksessa hävittää KOKO historian.

Mistään näistä tiimiläisiltäsi ei liikene kiitosta, joten älä käytä –forcea.

Tiimityö ja versionhallinnan konfliktit (kesto 24:12)

Yksinkertaisen konfliktin korjaaminen

Kun konflikti tapahtuu, Git tiedottaa siitä selkeästi. Tietoa tilanteesta saa komennolla git status, jota on muutenkin hyvä käyttää versionhallintaa käyttäessään tietovaraston tilan seuraamiseksi.

$ 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 <file>..." to mark resolution)

both modified:   conflict.txt

Git merkitsee tiedostoon itseensä kohdat, jotka ovat konfliktissa:

$ less conflict.txt
<<<<<<< HEAD
one opinion on input
=======
another opinion on the same line
>>>>>>> conflicting-branch

======= merkitsee konfliktissa olevien commitien välistä rajaa: Kaikki sisältö rivin <<<<<<< HEAD ja sen välissä kuvaa sillä hetkellä etärepositoriossa olevaa sisältöä, johon HEAD osoittaa. Vastaavasti kaikki sen alapuolella ``>>>>>>> conflicting-branch``iin saakka kuvaa sisältöä, joka löytyy juuri lisättävästä commitista.

Korjaus tehdään editoimalla tiedostoa niin, ettei konfliktimarkkereita tiedostossa enää ole. Tämä on sinänsä suoraviivainen tehtävä, mutta vaatii kommunikaatiota ja tarkkuutta, koska on tehtävä päätös, mikä muutos jää lopulta voimaan: oma, toisen tekemä vai mahdollisesti molempien yhdistelmä. Tiedoston korjauksen jälkeen itse korjaus viedään uutena commitina versionhallintaan:

git add conflicts.txt
git commit -m"Resolved merge conflict as discussed"
git push origin HEAD

Olennaista on muistaa, ettei kukaan tiimiläisistä ole yksin projektissa, joten konfliktin korjaaminen ei ole oman commitin läpisaamista Konflikteilta voidaan kokonaan välttyä, jos kaikki ryhmän jäsenet työskentelevät omissa kehityshaaroissaan. Tällöin voidaan pitää yksi päähaara sellaisessa tilassa, josta kuka tahansa voi lähteä työskentelemään projektin parissa. Kun yksi henkilö saa jonkin ominaisuuden toteutettua ja testattua eli julkaisukelpoiseen tilaan se voidaan yhdistää osaksi päähaaraa.

Git-demo (kesto 13:27)