Tämä juttu kertoo CVS-ohjelmistosta (Concurrent Versions System) ja sen käytöstä. Tämä ei ole käyttöohje, mutta lopussa on kyllä linkki sellaiseenkin. Itse asiassa suosittelen tämän jutun lukemista ennen itse käyttöohjeita, erityisesti jos et vielä tiedä CVS:n käytöstä mitään.
CVS on ilmainen ohjelmisto, joka on luotu helpottamaan ohjelmistojen versionhallintaa. Lisäksi CVS mahdollistaa sen, että useat kehittäjät voivat tehokkaasti kehittää yhtä sovellusta ilman suuria ongelmia mm. samojen lähdetiedostojen editoinnista. Käytännössä CVS:n toiminnan ydin on lähdekoodin kehityksen historian tallentaminen ja mihin tahansa tilanteeseen palaamisen mahdollistaminen.
Tässä jutussa käytetään ilmaisuja "ohjelmisto" ja "koodi" aika löysästi: tosiasiassa CVS ei ota kantaa arkistoimansa materiaalin sisältöön, vaan sillä voi tallentaa ihan mitä tahansa tiedostoja. Parhaiten CVS:n hyödyt tulevat kuitenkin esiin silloin, kun projektin olennaisesti muuttuvat tiedostot ovat tekstimuotoisia (lähdekoodia, HTML-sivuja, XML:ää tms.). Ohjelmisto voi siis yhtä hyvin tarkoittaa omaa www-sivustoasi ja koodi yksittäisiä HTML-sivuja.
CVS ylläpitää kaikkea koodia omassa tallessaan emokopiossa (ns. repositoryssa), johon käyttäjä ei ikinä koske suoraan. Kun käyttäjä haluaa tehdä jotain koodille - esimerkiksi muokata sitä tai vaikka kääntää sen ajettavaksi ohjelmaksi - hän ottaa käyttöönsä työkopion. Tästä toimenpiteestä käytetään nimitystä checkout.
Checkoutin jälkeen käyttäjällä on kopio, jonka kanssa hän voi tehdä mitä haluaa. Muutokset eivät kuitenkaan päivity suoraan emokopioon, joten käyttäjä voi vaikka sotkea kaiken; jos hän haluaa palata takaisin vanhaan tilanteeseen, hän voi vain pyytää CVS:ää palauttamaan repositorysta uusimmat versiot käyttöönsä. Mikäli käyttäjä pitää tekemiään muutoksia hyvänä, hän voi tallentaa muutokset myös emokopioon. Tästä toiminnosta käytetään nimeä commit.
Jokaisen commitin yhteydessä tiedostosta syntyy uusi versio. CVS antaa sivuille versionumerot, jotka lähtevät 1.1:stä. Jokainen commit kasvattaa jälkimmäistä numeroa yhdellä, joten esimerkiksi kolmen muutoskerran jälkeen tiedoston versionumero on 1.4. Huomaa, että näillä versioilla ei ole mitään tekemistä esim. koodattavan ohjelmiston versionumeron kanssa - nämä vain kuvastavat tiedostojen kehitystä. Versionumerolla voidaan helposti viitata mihin tahansa tiedostosta olemassa olleeseen versioon.
Ylläoleva kuulostaa (versionumerointia lukuunottamatta) toiminnallisesti melkein samalta kuin mitä huolellinen varmuuskopioiden ottaminen parhaimmillaan on - jos siis kuvitellaan, että varmuuskopiohakemistosi vastaisi CVS:n repositorya ja työhakemistosi CVS:n luomaa työkopiota. Tämä ei kuitenkaan ole koko totuus. Mitä eroa on commitilla ja varmuuskopion päivittämisellä?
Keskeisin ero on se, että siinä missä varmuuskopion päivittäminen hävittää aiemman version tiedostosta, commit ei tee sitä. (Toki on teoriassa mahdollista varmuuskopioida tiedosto jokaisen muutoksen jälkeen omalle nimelleen, mutta tätä tuskin kovin moni viitsii tehdä - sen jälkeen varmuuskopioon palaaminen on jo melkoista akrobatiaa!) Toinen olennainen ero on siinä, että varmuuskopion tekeminen ylikirjoittaa mahdollisesti muiden tekemät muutokset; CVS ei tee näin.
Kolmas merkittävä ero on se, että CVS-commitin yhteydessä ohjelmoija voi myös kirjoittaa lokiin merkinnän siitä, mitä tehdyt muutokset oikeasti tarkoittavat ja miksi ne on tehty. Tämä on toki vain apuväline: muutoskirjanpitoahan voi tehdä muutenkin, CVS vain helpottaa sitä sitomalla kirjatut kommentit tiiviisti ja selkeästi tehtyihin muutoksiin.
Kuvitellaan, että meillä on esimerkiksi seuraava yksinkertainen HTML-tiedosto nimeltä linkit.html
, jota CVS:ää käyttävät Jaska ja Pena haluavat muokata.
<html> <head><title>Jaskan ja Penan linkit</title></head> <body> <ul> <li><a href="sivu1.html">Quake-aiheiset linkit</a></li> <li><a href="sivu2.html">Matkailuaiheiset linkit</a></li> </ul> </body> </html>
Eräänä iltana Jaska päättää lisätä sivulle linkin Hesarin etusivulle. Hän luo CVS:llä itselleen oman työkopion ja ryhtyy muokkaamaan sitä. Pena puolestaan on jo varttia aikaisemin imaissut itselleen oman työkopion, sillä hän on aikeissa vaihtaa sivun title-otsikkoa. Molemmilla on nyt työkopiossaan ylläoleva versio HTML-sivusta, jota he lähtevät muuttamaan.
Ensin tulee valmiiksi Pena. Hän on muuttanut title-elementin sisälle tekstin "Universumin parhaat linkit" ja suorittaa commitin. Emokopioon päivittyy tuo uusi title-elementti, ja Pena lähtee nukkumaan. Sillä välin Jaska on saanut lisättyä hesarilinkin sivulleen ja on valmiina päivittämään muutoksensa emokopioon. Mutta mitä nyt tapahtuu? Jaskan työkopiossahan on edelleen vanha title-elementin sisältö, koska Penan muutos tuli emokopioon vasta sen jälkeen, kun Jaska oli jo imaissut oman työkopionsa. Jos Jaskan työversio kopioitaisiin suoraan emoon, Penan tekemä päivitys ylikirjoittuisi. Se ei tietenkään käy.
Kun Jaska yrittää commitata muutoksensa, CVS huomauttaa hänelle, että emokopio on päivittynyt. Jaska pyytää CVS:ää päivittämään emokopion muutokset itselleenkin. Nyt tapahtuu muutosten yhdistäminen (ns. merge): CVS tutkii, mitkä osat emossa ovat muuttuneet sen jälkeen, kun Jaska otti oman työkopionsa, ja liittää nämä muutokset Jaskan työkopioon. Nyt Jaskan työkopio päivittyy siten, että siinä on mukana myös Penan tekemä title-muutos. Jaska testaa, että uusi kopio toimii edelleen, ja valitsee sitten commitin. Näin repositoryyn päivittyy kopio, jossa on tallessa molempien tekemät muutokset.
Muutosten yhdistämistä ei tietenkään ole aina mahdollista tehdä täydellisesti: jos sekä Jaska että Pena olisivat muuttaneet title-otsikkoa, CVS ei voi tietää, kumpaa versiota pitäisi noudattaa. Näissä konfliktitilanteissa CVS näyttää muuttuneet tiedostot siten, että käyttäjä voi helposti muokata lopputuloksen yhtenäiseksi - siis esimerkiksi valita, kumman asettamaa titleä lopulta käytetään. Olennaista on kuitenkin se, että CVS ei yhdistä tiedostoja jos sitä ei voi luotettavasti tehdä, vaan jättää yhdistelemisen käyttäjän harkittavaksi. Hyvin organisoidussa projektityössä tällaiset konfliktit ovat tosin hyvin harvinaisia.
Muutosten yhdistelemisen lisäksi CVS:stä on muutakin hyötyä. Ensinnäkin jokaisesta tiedostosta syntyy muutosloki, jossa kerrotaan jokaisesta muutoksesta tekijä, ajankohta, mitä on tehty (koodin tasolla: mitkä rivit ovat muuttuneet ja miten) ja lisäksi vielä käyttäjän tekemä kommentti. Näillä tiedoilla on helpompaa seurata esimerkiksi jonkin tietyn rutiinin kehityshistoriaa.
Lokitiedoista voi konstruoida myös ns. annotaationäkymän, joka kertoo jokaisen koodirivin tekijän ja version. Tuo näkymä voisi aiemmin esimerkkinä käytetyn html-tiedoston osalta olla esimerkiksi seuraavanlainen (tässä oletetaan, että sivu esimerkkimme sijoittui aikaan, jossa sivusta oli olemassa vain Penan tekemä ensiversio). Kiinnitä erityistä huomiota aiemman esimerkin muutoksiin: titlen sisältävään riviin ja toisaalta ilmestyneeseen Hesari-linkkiin.
Pena (1.1) | <html> |
Pena (1.2) | <head><title>Universumin parhaat linkit</title></head> |
Pena (1.1) | <body> |
Pena (1.1) | <ul> |
Pena (1.1) | <li><a href="sivu1.html">Quake-aiheiset linkit</a></li> |
Pena (1.1) | <li><a href="sivu2.html">Matkailuaiheiset linkit</a></li> |
Jaska (1.3) | <li><a href="http://www.helsinginsanomat.fi/">Hesari</a></li> |
Pena (1.1) | </ul> |
Pena (1.1) | </body> |
Pena (1.1) | </html> |
CVS on omiaan muutosten tarkasteluun. Kuten jo aiemmin todettiin, jokaisen tiedoston jokainen versio saa oman versionumeronsa (sekaannusten välttämiseksi tiedostojen versioista puhutaan usein revisioina). Kun tiedostojen muodostamasta ohjelmasta tms. sitten julkaistaan joku versio, tämä ohjelman versio koostuu joukosta tiedostojen tiettyjä revisioita, jotka tyypillisesti olivat uusimmat sillä hetkellä kun softa julkaistiin.
Esimerkiksi "Omasofta 2001" voisi koostua vaikkapa omasofta.cpp:n revisiosta 1.8, tiedostot.cpp:n revisiosta 1.4 ja ohje.txt:n revisiosta 1.5. "Omasofta 2002" puolestaan voisi koostua omasofta.cpp 1.12:sta, tiedostot.cpp 1.5:sta ja ohje.txt 1.6:sta. Näin siis jokainen julkaisuversio vastaa joukkoa tiedostojen revisioita. Koska numeerinen merkintä on varsin kömpelö jo pienissä projekteissa, tällaisille joukoille voi antaa tunnisteita eli tageja. Tageilla voidaan merkitä esimerkiksi yhden julkaisuversion tiedostot yhteenkuuluviksi.
Versioinnin ja tagien käytön edut tulevat esiin ensinnäkin silloin, kun joku menee rikki: siis ohjelmaan syntyy bugi, jota ei aiemmissa versioissa ollut. CVS:llä on helppo katsoa, mitä kohtia esimerkiksi tiedostot.cpp:ssä on muutettu Omasofta 2001:n ja 2002:n välissä, ja usein jo tämä tieto auttaa merkittävästi bugin korjaamisessa. Vastaavasti on myös vaivatonta palata vanhempiin kehitysversioihin, jos se jostain syystä on tarpeellista. Esimerkiksi version 2001 lähdekoodit löytyvät yhdellä komennolla vielä vuonna 2005:kin.
Eräs CVS:n vaikeimmin hallittavista ominaisuuksista on oksien (branches) käyttäminen. Oksat ovat tarpeellisia silloin, kun samasta ohjelmasta kehitetään yhtä aikaa useampaa versiota. Tarve kuulostaa kovin erikoiselta, mutta ei oikeastaan ole sitä. Kuvitellaan, että aiemmin mainittu Omasofta 2002 julkaistaan, ja siitä löytyy pari vakavaa bugia. Niiden korjaaminen olisi helppoa, mutta asioita monimutkaistaa se, että 2003:n kehitys on jo kovassa vauhdissa, ja lähdekoodi ei ole ollenkaan samassa tilassa kuin missä se oli 2002:n aikaan.
CVS-henkinen ratkaisu pulmaan on se, että palataan CVS:llä version 2002 lähdekoodiin ja haarautetaan siitä kohtaa uusi oksa, johon bugikorjaukset tehdään. Oksa käyttäytyy aivan itsenäisesti ja irrallaan emoversiosta, joka saattaa olla jo vaikka kuinka kaukana alkuperäisestä versio 2002:n tilanteesta. Luodun oksan pohjalta voidaan vaikkapa julkaista versio 2002b, jossa on mukana tarvittavat bugikorjaukset, mutta ei versioon 2003 tehtäviä uudistuksia (eikä myöskään niiden mukana tulevia uusia bugeja!). Kun 2003:n kehitys on sitten sopivassa vaiheessa, oksat voi jälleen yhdistää, jolloin 2002b:hen tehdyt bugikorjaukset liimataan myös 2003:n koodiin. Tämä toiminto vastaa olemukseltaan melko tarkasti aiemmassa esimerkissä esitettyä useamman kehittäjän muutosten yhdistelyä.
Oksaksi voi haarauttaa myös radikaaleja koodin uudistuksia: esimerkiksi 3D-räiskinnän kehittäjien kannattaisi irrottaa uuden grafiikkamoottorin toteutus kokonaan omaan oksaansa, jolloin muiden toimintojen kehittäminen ei häiriinny, ja uusi moottori voidaan myöhemmin istuttaa takaisin runkokoodiin oksan yhdistämisellä. Näin laajat uudistukset voidaan toteuttaa ilman, että kaikkien kehittäjien täytyy olla varpaillaan niiden vuoksi.
Eräs huomattava oksien käyttötapaus avautuu, kun pohditaan avoimen lähdekoodin maailmassa yleistä softien muuntelua omaan käyttöön. Jos asennan monikansallisen kehittäjätiimin tekemän MegaSofta 2.0:n koneelleni ja teen siihen tarvitsemiani muutoksia, MegaSofta 2.1:n ilmestyessä harmittaa: jos kopioin 2.1:n lähdekoodin suoraan muuntelemani 2.0:n päälle, muutokseni ylikirjoittuvat. Vaihtoehtona on siis lähinnä muutosten tekeminen käsin uudelleen tai sitten päivittämättä jättäminen.
Kumpikaan ei ole hyvä vaihtoehto, mutta CVS auttaa tässä paljon. Kun siirtää lähdekoodin heti aluksi CVS:ään, voi kehittäjien tekoset ja omat muutokset sijoittaa omiin oksiinsa. Aina uuden kehittäjäversion ilmestyessä oksat voi yhdistää, ja jatkaa sitten jälleen kehitystä erillään. Tyypillisesti suurin osa kehittäjäversioiden muutoksista yhdistyy ilman konflikteja, ja loput on yleensä melko vaivatonta korjailla käsin. Täysin automaattiseksi CVS ei päivityspuuhaa tee, mutta helpottaa sitä paljon.
Aiemmin on käsitelty vain CVS:n ominaisuuksia ja vaikutuksia ohjelmistokehitykseen. Tässä vielä lyhyt katsaus siihen, millainen sovellus CVS oikeastaan on ja miten se toimii. Jo heti aluksi on syytä todeta, että CVS:n lähdekoodi on avoin, ja softa kääntyy lähes kaikille käyttöjärjestelmille. Windowsisteille löytyy tietysti valmiit binääritkin.
CVS:ää voi käyttää joko itsenäisenä sovelluksena tai client/server-mallilla. Yksittäisille kehittäjille ja kotikäyttäjille itsenäisenä sovelluksena ajaminen on kätevintä. Tällöin CVS on vain yksi ajettava ohjelmatiedosto, joka käyttää repositoryn tallentamiseen jotain paikallista hakemistoa.
Laajemmissa työympäristöissä ja erityisesti useita alustoja (Windows, Unixit tms.) kattavissa projekteissa on järkevämpää siirtyä ennemmin tai myöhemmin palvelinmalliin. Ainakin unix- ja Windows-alustalle on saatavilla CVS-palvelinsofta, joka hoitaa repositoryn varastoinnin ja käyttäjien palvelemisen. Tähän CVS-palvelimeen otetaan yhteyttä CVS-asiakasohjelmalla (joka on käyttöliittymältään täsmälleen samanlainen kuin jos CVS:ää käyttäisi itsenäisenä sovelluksena) TCP/IP-yhteyden yli. CVS-palvelin hoitaa mm. käyttäjätunnistuksen ja käyttöoikeuksien hallinnan. Yhteydet voidaan muodostaa myös SSH-putken yli, jolloin lähdekoodi pysyy paremmin turvassa.
Palvelinmalli mahdollistaa hyvinkin hajanaisen sovelluskehityksen, koska lähdekoodin emokopio voidaan pitää aina yhdessä paikassa ja kehittäjät voivat sijaita missä tahansa. Hyvä esimerkki tällaisesta käytöstä on esimerkiksi Mozilla, jonka lähdekoodi säilytetään keskitetyssä CVS-palvelimessa, josta ympäri maailmaa sijaitsevat kehittäjät hakevat itselleen päivitykset.
CVS:n peruskäyttöliittymä on komentorivipohjainen sekä Windowsilla että Unixilla. Verrattuna moniin perinteisiin unix-työkaluihin CVS on jopa kohtuullisen luettava ja helppokäyttöinen, mutta sen käyttäminen vaatii hyvää hakemistorakenteiden hallintaa (eikö ohjelmistojen kehitystyö yleensä?) ja hieman kärsivällisyyttä aluksi. Toisaalta käyttöliittymä on hyvin selkeä ja nopea pienen totuttelun jälkeen, joten suurta kuormaa itse työntekoon ei CVS:n käytöstä tule.
Ainakin Windows- ja Mac-ympäristöissä CVS:ään on saatavilla myös graafinen käyttöliittymä. Niiden käyttäminen ei ole täysin ongelmatonta eikä kaikilta osin yhtä loogista kuin komentoriviversioiden, mutta käyttöliittymän tuttuus on tietysti merkittävä apu. Itse kukin harkitkoon, mitä pitää sopivana.
CVS-repositoryn selailuun ja erilaisten loki- ja annotaationäkymien katseluun on siivompiakin työkaluja yllin kyllin, eli komentorivipohjaista CVS-ohjelmaa tarvitsee käyttää vain päivitysten yhteydessä. Eräs käyttökelpoisimmista välineistä on ViewCVS, joka mahdollistaa CVS-puiden katselun ja muutosten tutkiskelun suoraan www-selaimella. Muitakin välineitä on.
Vastaus riippuu siitä, onko nykyinen softankehitysmallisi tyydyttävä vai ei. Seuraavassa oletetaan, että et tällä hetkellä käytä mitään versionhallintaa; jos käytät, vertaile CVS:n ja käytössä olevan järjestelmän ominaisuuksia ja mieti, kannattaako vaihtaa.
Ei välttämättä mitenkään, mutta olisi suotavaa että se vaikuttaisi. CVS antaa hyvän alustan ohjelmoida järjestelmällisesti ja selkeästi. Lisäksi se tietysti tuo vähän ylimääräisiä askelia koodaukseen, koska muutoksia pitää välillä aina commitata, dokumentoida ja niin edelleen. Toisaalta tämän hidastava vaikutus ei ole kovin suuri, ei ainakaan hyötyihin nähden.
On järkevää asettaa kehitykselle CVS:n suhteen kaksi tavoitetta: 1) repositoryyn ei koskaan commitata toimimatonta koodia (eli emokopiosta vetäistyn version sorsien pitää kääntyä, webbisivun toimia - tai mikä nyt onkin sopiva mittari) ja 2) committien pitäisi olla niin pieniä kuin mahdollista.
Käytännössä tämä vaikuttaa koodausfilosofiaan siten, että ei saisi alkaa koodaamaan periaatteella "luenpa tuosta tuon tiedoston läpi ja korjaan kaikki ongelmat mitä siinä tulee vastaan", koska tällöin tulee muuttaneeksi vähän kaikkea. Parempi on ensin käydä tiedosto läpi, listata ongelmat ja korjata ne yksitellen siten, että jokaisen ongelman korjaus commitataan erikseen. Tällöin tiedoston revisiot pysyvät selkeinä, koska jokaisessa muutetaan vain yhtä selkeästi dokumentoitua asiaa. Tätä ei toki kannata vetää naurettavuuksiin: on ihan ok hoitaa 15 tekstikorjausta pois alta kerralla, varsinkin jos nämä ovat keskenään samantyyppisiä.
Pidemmällä tähtäimellä CVS vaikuttaa siten, että koodi selkeytyy. Tätä helpottaa se, että CVS:llä on helppo katsoa, mitä muutoksia työkopion ja emon välillä on tehty. Siispä aina ennen committia kannattaakin tarkistaa nämä muutokset: Onko koodi selkeää? Näyttääkö nyt siltä, että tämä ei aiheuttaisi uusia ongelmia? Olenko varmasti muuttanut vain olennaisia kohtia? Näin repositoryyn ei ajaudu keskeneräistä ja huonosti kirjoitettua koodia. Se, että yhdellä kertaa koodaa vain yhtä asiaa, parantaa koodia myös sikäli, että ei tule niin helposti harhailtua asiasta toiseen ja unohdettua jotain olennaista.
Kokeile CVS:ää, jos teet softaa jolla on useita ulkopuolisia käyttäjiä. Hyöty on selvä, mutta kyse on lähinnä siitä, haluatko pakottaa itsesi toimimaan huolellisesti ja siten, että syntyvä CVS-historia on järkevä. Suosittelen, koska se kiistatta parantaa koodin laatua, ja usein niin paljon että kuluva aika on hyvin sijoitettu. Tämä pätee varsinkin silloin, jos teet softaa useita kuukausia tai jatkat sen kehitystä myöhemmin.
Yksin toimiessa CVS on myös hyvä tapa pitää koodipuu selkeänä. Esimerkiksi tilapäistiedostoja ja huonosti nimettyjä varmuuskopioita ei kannata ollenkaan lisätä CVS-järjestelmään, jolloin lähdekoodin emokopiossa on vain softan toiminnan kannalta tarpeellinen materiaali. Tämä helpottaa myös varmuuskopiointia: voit varmuuskopioida vain repositoryn luottaen siihen, että siellä on kaikki tarpeellinen - ja vain kaikki tarpeellinen.
Vastaus riippuu ennen muuta työtavoistanne. Yleensä kannattaisi kokeilla, koska kaikissa useamman tekijän projekteissa on aina päällekkäisten muutosten riski, jota CVS tehokkaasti eliminoi. Lisäksi CVS:n tuottama lokitieto voi olla arvokasta silloin, kun jonkin usean tekijän muutoksen aiheuttamia sivuvaikutuksia yritetään selvitellä.
Toisaalta CVS:n käyttöönotto vaatii jonkinlaista uudelleenorientoitumista, erityisesti jos tapana on ollut korjata koodia periaatteella "No mä korjaan tän tässä samalla". Parasta olisi ottaa CVS käyttöön jo heti projektin alussa, jolloin pienten palasten koodaamisesta tulee kaikille tapa. Kesken projektin käyttöönotettu CVS aiheuttaa aluksi paljon hämminkiä, kunnes tilanne tasoittuu. Lopulta CVS maksaa imemänsä ajan takaisin, kun jatkokehitys ja ongelmien selvittely nopeutuu.
Asiaan vaikuttaa tietysti myös hajautuskysymys: jos projektin tekijät työskentelevät eri paikoissa, CVS:n kaltainen työkalu helpottaa suunnattomasti lähdekoodin emoversioiden kasassa pitämistä. On erittäin suositeltavaa panostaa tähän, koska epämääräisten lähdekoodiversioiden kertyminen hakemistoihin on melkoinen ongelma pidemmän päälle. Usein sitä kaipaisi, että joku kertoisi, onko tämä nyt varmasti uusin versio lähdekoodista. CVS on oikein käytettynä tuo joku.
Aiempi teksti on kuulostanut siltä, kuin yrittäisin tyrkyttää CVS:ää kaikille. En, koska se ei sovellu kaikille. Sen sijaan suosittelen kaikkeen vakavaan ohjelmistokehitykseen oikeaa asennetta, johon mielestäni kuuluu monia sellaisia asioita, joiden toteuttamisessa CVS on merkittävästi avuksi. Siksi suosittelenkin sitä kaikkiin vähänkin suurempiin projekteihin, koska alkukankeuden jälkeen apu on merkittävä.
CVS ei kuitenkaan ratkaise softakehityksen kaikkia ongelmia. Konfliktimuutosten havaitsemisessa sen kyvyt rajoittuvat tekstin muodollisiin ristiriitoihin: yhden rivin sisällön pitää olla yksikäsitteinen. CVS ei kuitenkaan mitenkään estä sitä, etteikö toinen kehittäjä voisi muuttaa vaikkapa jonkin rajapinnan määrittelyä siten, että muiden koodi ei enää toimi - tiimien sisäinen kommunikointi ja koordinointi siis on edelleen keskeisessä asemassa. CVS:n käyttöönotto enemmänkin korostaa tiettyjä ongelmia, ja niihin on oltava valmiina paneutumaan - on kyse sitten yhden tai tuhannen ihmisen projektista.
Jouni Heikniemi 18.4.2002
Tämä dokumentti kuuluu sivustoni
osioon Kirjallisia tuotoksia.