Lähestymistapoja versionhallintaan

Kaikilla versionhallintajärjestelmillä on sama perusongelma: kuinka sallia käyttäjien jakaa tietoa, mutta estää heitä astumasta vahingossa toistensa varpaille? Käyttäjien on aivan liian helppoa vahingossa ylikirjoittaa toistensa tekemät muutokset arkistossa.

Jaettujen tiedostojen ongelma

Oletetaan, että meillä on kaksi työntekijää, Harry ja Sally. He päättävät muokata samaa arkiston tiedostoa samaan aikaan. Mikäli Harry tallettaa muutoksensa arkistoon ensin, on mahdollista, että Sally voi (hetkeä myöhemmin) vahingossa ylikirjoittaa ne omalla, uudella versiollaan tiedostosta. Vaikka Harryn versio tiedostosta ei häviä ikuisiksi ajoiksi (koska tiedostojärjestelmä muistaa kaikki muutokset) , Harryn tekemät muutokset eivät ole mukana Sallyn uudemmassa versiossa tiedostosta, koska hän ei koskaan edes nähnyt Harryn muutoksia. Harryn työ on tosiasiallisesti kadonnut (tai ainakin puuttuu tiedoston viimeisestä versiosta) ja luultavasti vahingossa. Juuri tätä tilannetta halutaan välttää!

Kuva 2.2. Vältettävä ongelma

Vältettävä ongelma

Lukitse/muuta/vapauta -ratkaisu

Monet versionhallintajärjestelmät ratkaisevat tämän ongelman lukitse/muuta/vapauta -mallin avulla. Tällainen ratkaisu on hyvin yksinkertainen; arkisto sallii vain yhden ihmisen muuttaa tiedostoa kerrallaan. Ensiksi Harryn pitää lukita tiedosto, ennen kuin muutoksia voidaan alkaa tehdä. Tiedoston lukitseminen muistuttaa paljolti kirjan lainaamista kirjastosta; jos Harry on lukinnut tiedoston, niin Sally ei voi tehdä siihen muutoksia. Mikäli Sally koettaa lukita tiedoston, arkisto evää pyynnön. Sally voi ainoastaan lukea tiedostoa ja odottaa, että Harry saa muutostyönsä loppuun ja vapauttaa lukon. Lukon vapauttamisen jälkeen Sally voi vuorostaan lukita ja muokata tiedostoa.

Kuva 2.3. Lukitse/muuta/vapauta -ratkaisu

Lukitse/muuta/vapauta -ratkaisu

Lukitse-muokkaa-vapauta -mallin ongelma on, että se on hieman rajoittava ja muodostuu usein käyttäjille pullonkaulaksi:

  • Lukitus voi aiheuttaa hallinnollisia ongelmia. Joskus Harry lukitsee tiedoston ja sitten unohtaa sen. Tällä välin, koska Sally yhä odottaa tiedostoa, hän ei voi tehdä muuta. Ja sitten Harry lähtee lomalle. Nyt Sallyn täytyy löytää ylläpitäjä vapauttamaan Harryn lukko. Tilanne päättyy aiheuttaen paljon tarpeetonta viivettä ja hukattua aikaa.

  • Lukitus voi aiheuttaa tarpeetonta sarjallistumista. Mitä tapahtuu, jos Harry on muokkaamassa tekstitiedoston alkuosaa, ja Sally haluaa muokata saman tiedoston loppua? Nämä muutokset eivät ole päällekkäisiä. He voisivat helposti muokata tiedostoa yhtä aikaa, eikä ongelmia syntyisi, olettaen että muutokset yhdistetään oikein. Tässä tilanteessa ei ole tarpeen vuorotella.

  • Lukitus voi luoda valheellisen turvallisuuden tunteen. Oletetaan, että Harry lukitsee ja muokkaa tiedostoa A, kun Sally samaan aikaan lukitsee ja muokkaa tiedostoa B. Oletetaan vielä, että A ja B riippuvat toisistaan, ja että tehdyt muutokset ovat semanttisesti ristiriitaisia. Yhtäkkiä A ja B eivät enää toimikaan yhdessä. Lukitusjärjestelmä oli voimaton estämään ongelman - ja silti se jollain tapaa antoi valheellisen turvallisuuden tunteen. Harryn ja Sally on helppoa kuvitella, että lukitsemalla tiedostot kumpikin aloittaa varman, eristetyn toimenpiteen; siten lukitus estää heitä keskustelemasta aikaisessa vaiheessa epäyhteensopivista muutoksistaan.

Kopioi-muokkaa-yhdistä -ratkaisu

Subversion, CVS ja monet muut versionhallintajärjestelmät käyttävät kopioi-muokkaa-yhdistä -mallia vaihtoehtona lukitukselle. Tässä mallissa kunkin käyttäjän asiakasohjelma lukee arkistoa ja muodostaa henkilökohtaisen työkopion projektista. Käyttäjät työskentelevät sitten yhtä aikaa, kukin muokaten omia kopioitaan. Lopulta omat kopiot yhdistetään uudeksi, lopulliseksi versioksi. Versionhallintajärjestelmä auttaa usein yhdistämisessä, mutta loppujen lopuksi käyttäjä on vastuussa siitä, että yhdistäminen tapahtuu oikein.

Esimerkki. Oletetaan, että Harry ja Sally luovat kumpikin työkopion samasta projektista kopioimalla sen arkistosta. He työskentelevät yhtä aikaa, ja tekevät muutoksia samaan tiedostoon A työkopioissaan. Sally tallettaa muutoksensa arkistoon ensin. Kun Harry yrittää tallettaa muutoksensa myöhemmin, arkisto kertoo hänelle, että hänen tiedostonsa A on vanhentunut. Toisin sanoen tiedosto A on jotenkin muuttunut arkistossa sen jälkeen, kun hän viimeksi kopioi sen. Joten Harry pyytää asiakasohjelmaansa yhdistämään uudet muutokset arkistosta oman työkopionsa tiedostoon A. Sallyn tekemät muutokset eivät mene päällekkäin hänen omien muutostensa kanssa, joten saatuaan muutokset yhdistettyä hän voi tallettaa työkopionsa takaisin arkistoon.

Kuva 2.4. Kopioi-muokkaa-yhdistä -ratkaisu

Kopioi-muokkaa-yhdistä -ratkaisu

Kuva 2.5. ...Kopioi-muokkaa-yhdistä jatkuu

...Kopioi-muokkaa-yhdistä jatkuu

Mutta entäpä jos Sallyn muutokset ovatkin päällekkäisiä Harryn muutosten kanssa? Mitä sitten? Tällaista tilannetta kutsutaan ristiriidaksi, eikä se yleensä ole kovin suuri ongelmaa. Kun Harry komentaa asiakasohjelmaansa yhdistämään viimeisimmät muutokset arkistosta työkopioonsa, hänen kopionsa tiedostosta A merkitään ristiriitaiseksi: hän voi tarkastella molempia ristiriitaisten muutosten joukkoja, ja käsin valita niiden välillä. Huomaa, että ohjelma ei voi automaattisesti ratkoa ristiriitoja; vain käyttäjä (ihminen) kykenee ymmärtämään ne ja tekemään tarpeelliset älykkäät valinnat. Kun Harry on käsin ratkonut päällekkäiset muutokset (ehkäpä keskustelemalla ristiriidoista Sallyn kanssa!), hän voi turvallisesti tallettaa yhdistetyn tiedoston takaisin arkistoon.

Kopioi-muokkaa-yhdistä -malli voi kuulostaa hieman kaoottiselta, mutta käytännössä se toimii äärimmäisen joustavasti. Käyttäjät voivat työskennellä yhtä aikaa, tarvitsematta koskaan odottaa toisia. Silloinkin, kun työ kohdistuu samoihin tiedostoihin, useimmat yhtäaikaiset muutokset eivät ole päällekkäisiä, ja siten ristiriidat ovat harvinaisia. Ristiriitojen ratkomiseen tarvittava aika on paljon pienempi kuin lukitusjärjestelmän käytössä hukattu aika.

Loppujen lopuksi kaikki tiivistyy yhteen kriittiseen tekijään: käyttäjien kommunikointiin. Kun käyttäjät kommunikoivat huonosti, sekä syntaktisten että semanttisten ristiriitojen määrä kasvaa. Mikään järjestelmä ei voi pakottaa käyttäjiä kommunikoimaan täydellisesti, eikä mikään järjestelmä pysty havaitsemaan semanttisia ristiriitoja. Niinpä ei kannata tuudittautua harhaluuloon, että lukituksiin perustuva järjestelmä voisi jotenkin estää ristiriidat; käytännössä lukitus vaikuttaa enemmänkin tuottavuutta rajoittavasti.

On eräs tavallinen tilanne, jossa lukitse-muokkaa-vapauta -malli toimii paremmin: tiedostot, joita ei voi yhdistää. Jos arkistossasi on esimerkiksi kuvia, joita kaksi ihmistä muuttaa yhtä aikaa, niin tehtyjä muutoksia ei voi mitenkään yhdistää. Joko Harry tai Sally menettävät muutoksensa.

Mitä Subversion tekee?

Subversion käyttää oletusarvoisesti kopioi-muokkaa-yhdistä -mallia, ja useissa tapauksissa et koskaan tarvitse mitään muuta. Versiosta 1.2 alkaen Subversion tukee kuitenkin myös tiedostojen lukitusta, joten jos projektissasi on tiedostoja, joita ei voi yhdistää (tai projektikäytäntö edellyttää lukitusmallin käyttöä), Subversion tarjoaa silti tarvittavat ominaisuudet.