Versionhallintahistorian roskautumisen välttäminen

Jatkona Teemun kirjoitukseen versionhallinnan vajaakäytöstä:

Ohjelmiston kehitys tapahtuu usein kiemuroiden kautta: kokeillaan jotain, jota myöhemmin joudutaan korjaamaan, ja tehdään ajoittain myös yksinkertaisempia virheitä joita pitää oikaista. Nämä kiemurat lisäävät kohinaa versionhallintahistoriaan: versioiden määrä kasvaa ja loogiset muutokset levittyvät usean version yli. Selkeämpää olisi jos versioita olisi vähemmän ja ne vastaisivat loogisia kokonaisuuksia.

Git (ja muut hajautetut versiohallintajärjestelmät vastaavilla tavoilla) sallii seuraavan sarjan komentoja, jolla voi muuttaa juuri tallennettua versiota:

[muutoksia tiedostoihin]
$ git commit -m "Muutoksia."
[korjauksia viime muutokseen]
$ git commit --amend -m "Muutoksia, tällä kertaa oikein!"

Viimeinen komento ”–amend” -vivulla näennäisesti ylikirjoittaa edellisen version! Minkä takia tällaista sallitaan, ja milloin siitä on hyötyä? Nimenomaan kun halutaan vähentää versionhallintahistorian roskautumista, eli turhien versioiden lisäämistä. Kun kyse ei ole loogisesta muutoksesta, vaan korjauksesta edelliseen muutokseen, voi olla parempi päivittää aikaisemman version kuin lisätä uuden.

Miten versionhallintahistorian muokkaaminen (l. aikaisemman version ylikirjoittaminen) tällä tavalla voi onnistua? Hajautetuissa versionhallintajärjestelmissä commit ei enää tarkoita sitä, mitä se tarkoitti niitä edeltävissä keskitetyissä versionhallintajärjestelmissä (esim. CVS ja Subversion):

git commit = tallenna versio
cvs/svn commit = tallenna versio _ja_ julkaise

Julkaiseminen tarkoittaa tässä siis uuden version julkaisemista muille versionhallinnan käyttäjille. Tästä erosta seuraa että niin kauan kun muutos ei ole julkaistu, voidaan hajautetussa järjestelmässä hallitusti muuttaa paikallisen säiliön historiaa (ja sen jälkeen julkaista muutokset erillisenä askeleena ”git push” -komennolla).

Tämä mahdollisuus korjata jo tallennettuja versioita ennen kuin ne julkaistaan osoittautuu käytännössä hyvinkin hyödylliseksi: usein pieniä virheitä tulee tarpeen korjata juuri siinä viimeisessä versioissa.

Pitämällä versiot mahdollisimman yhtenäisinä versiohistorian seuraaminen ja muut versionhallintaoperaatiot helpottuu. Hajautetut versionhallintajärjestelmät auttavat versiohistorian roskautumisen välttämisessä tarjoamalla toiminnallisuutta kuin esim. ”git commit –amend” ja ”git rebase”.

Tämän artikkelin on kirjoittanut Markus Holmberg  ja sitä ovat sittemmin muokanneet muut Codenton työntekijät.

Operaattorit ja bitinnypläys

On yleisesti tunnustettu totuus, että C:n operaattorien sidontajärjestys tarvitsee välttämättä vertailu- ja bittioperaatioiden vaihdon. Esimerkki: a >> 5 & 3 == 1 && b >> 7 & 15 == 8. Melko selkeästi tarkoitetaan (((a >> 5) & 3) == 1) && (((b >> 7) & 15) == 8), mutta C:ssä, ja sen vaikutuksesta yllättävän monessa ohjelmointikielessä, kääntäjä ei tätä näin tulkitse. Sen sijaan jäsennys on ((a >> 5) & (3 == 1)) && ((b >> 7) & (15 == 8)), mikä on sekä eri asia kuin mitä tarkoitettiin, että suoraan sanottuna aivan järjetöntä.

Laadukkaampien kehitysympäristöjen eduksi on sanottava, että ne varoittavat tässä tilanteessa siitä, että luultavasti nyt ei tapahdu mitä kehittäjä luulee.

Joissain ohjelmointikielissä on järjestelty operaattorien sidonta uusiksi niin, että se on intuitiivisempi. Mielenkiintoinen kysymys on, miksi monessa uudessakaan kielessä, joka on tehnyt selkeän pesäeron menneisyyteen, ei ole koskettu sidontajärjestykseen. Tähän on kaksi kilpailevaa selitystä, joista helppo (ja luultavasti väärä) on se, etteivät kielen kehittäjät ole ymmärtäneet, että vaikka on olemassa status quo, se on virheellinen. Tämä ei ole uskottava selitys, koska kielten kehittäjät ovat yleisesti sekä älykkäitä että hyvin perehtyneitä ohjelmistotuotannon käytäntöihin.

Toinen selitys on, että pidetään C:mäisen syntaksin mindshareen kuuluvana asiana, että operaattorien merkitys ja sidontajärjestys on juuri se, mikä se oli C:ssä. Vaikka itse en aluksi pitänyt tätä uskottavana, sen puolesta puhuisi, että järjestyksen korjanneista kielistä C:mäisin on Ruby, eikä sekään ole mitenkään erityisen C:mäinen.

Ohjelmointikielien ryhmittely operaattorilogiikan mukaan

Kaavioon on ryhmitelty yleisesti käytössäolevia ohjelmointikieliä sen mukaan, miten ne sijoittuvat tarkasteltaessa niiden operaattorien logiikkaa tämän käyttötapauksen puitteissa. Oikean ja väärän lisäksi on kolme kysymyksenväistämiskategoriaa.

Ensimmäinen, Awk, Cobol, Modula-3, Lua ja SML ei tarjoa ensinkään operaattoreita bitinnypläykseen. Näissä kielissä pitää käyttää kirjastofunktioita.

Toinen kategoria on kielet, joissa syntaktiset käytännöt ovat riittävästi erilaiset, ettei ongelmaa oikeasti voi olla olemassakaan. Lispissä ja Schemessä suoritusjärjestys on tiukasti ilmaistu sulkeilla. Forthissa ja Joyssa suoritusjärjestys on yhtä tiukasti ilmaistu sillä, että ohjelmakoodi koostuu vuorottaisista parametrien asettelusta pinoon ja operaatioista, jotka ottavat syötteensä pinosta ja jättävät pinoon tuloksensa.

Kolmas kategoria on Smalltalk, Apl ja J. Nyt tarkkana: Nämä kielet näyttävät sikäli normaaleilta, että voi kirjoittaa lausekkeen 1 + 2 * 3 kun tarkoittaa 7. Vai voiko? Eipä voikaan, koska kaikki operaattorit ovat näissä samanarvoisia, ja lausekkeen arvo onkin 9, koska operaattorit käytetään vasemmalta oikealle, jos sulkeita ei ole.

Tässä käsitellyt ominaisuudet tuskin ovat toimineet kertaakaan ohjelmistotuotannon historiassa ensisijaisena toteutuskielen valintaperusteena. Todelliset valintakriteerit eivät ole näin järkeviä, mutta jos haluatte lukea niistä, Steve Yegge kirjoitti aiheesta jo vuosia sitten, eikä asiassa ole oikeasti muuttunut sen jälkeen mikään.

Tämän artikkelin on kirjoittanut Teemu Kalvas ja sitä ovat sittemmin muokanneet muut Codenton työntekijät.

Ohjelmistoalan ammattilaisia

Me Codentossa olemme kaikki* ohjelmistoarkkitehtejä, eli piirrämme kaavioita, joissa on monen värisiä laatikoita. Tämä erottaa meidät oikeista arkkitehdeistä, jotka tekevät julkisivuja, joissa on monen värisiä laatikoita.

Tämä ei kuitenkaan ole ainoa ohjelmistotyö jota teemme. Ohjelmistoalan moniosaajina toimimme tarvittaessa myös seuraavissa ammateissa:

Ohjelmistoarkeologi. Tämä Codenton lisäksi myös Vernor Vingen tuotannosta tuttu ohjelmistoammattilainen tutkii historiallisia jäänteitä ajalta ennen (tänä vuonna suosittujen) kielten kirjoitustaitoa, ja pyrkii rekonstruoimaan historiallisia ohjelmistoprojekteja.

Ohjelmistoantropologi koittaa henkilökohtaisen eläytymisen avulla ymmärtää ohjelmistoprojektin toimintaa: “Mitä v****a nää on oikein ajatelleet”

Ohjelmistofolkloristi tutkii kansanperinnettä joka selittää artefaktinaan syntyneen koodin: “Näin tää on aina tehty. Ei tässä mitään järkeä ole”

Ohjelmistostandupkoomikko esiintyy Codenton aamiaistilaisuuksissa ja on esittävinään jotain johon osallistumisen voi perustella työnantajalle.

Ohjelmisto-oikeuspatologi tutkii kuollutta projektia pyrkien selvittämään kuolinsyyn. Yleensä palvelulle on melko vähäinen kysyntä, koska kaikki haluavat vain unohtaa ikävän pieleen menneen projektin ja tehdä jotain uutta.

Ohjelmistopsykiatri kuuntelee ohjelmistoprojektin jäsenten murheita ja pyrkii auttamaan heitä kohtaamaan (ohjelmistoon liittyvät) vaikeat elämäntilanteensa. Codenton ohjelmistopsykiatrit soveltavat ratkaisukeskeistä terapiaa, jossa ongelmia käsitellään konkreettisten, pahaa oloa purkavien toimien kautta, eikä niinkään keskustella (ohjelmiston) lapsuudesta.

Ohjelmistomielisairaanhoitaja tukee ja valvoo ohjelmistoprojektia, annostelee tarvittavat lääkkeet ja yleisesti varmistaa etteivät mielenterveyden ongelmat aiheuta vaaraa projektille, sivullisille tai liiketoiminnalle.

Ohjelmistoviemärisukeltaja. No, olette varmaan kaikki tehneet tätä joskus. Mutta kaiken sen paskan seassa, syvällä labyrintin keskellä, on vuoto, ja jonkun on se etsittävä. Siis happinaamari päähän ja kuiluun.

* paitsi rakas programmausrüstunggeschäftsführerimme Tommi

Tämän artikkelin on kirjoittanut Otso Kivekäs ja sitä ovat sittemmin muokanneet muut Codenton työntekijät.