fredag den 17. april 2009

Git har ingen rename, og er stolt af det

Jeg sidder lige og fjoller rundt med mit seneste for-sjov projekt, og i den forbindelse besluttede jeg mig for at ændre på pakkestrukturen. Det er et Scala projekt, og derfor er sammenhængen imellem filnavne og klasse-/pakkenavne mere en konvention end en regel - men dels kan jeg lide den, og dels så skal man kun bryde konventioner, når man har rigtigt gode grund til det - så det endte med, at jeg også fysisk flyttede rundt på filerne.

Som tidligere nævnt her, så bruger jeg Git til versionskontrol, og da jeg ikke lige finde en oplagt måde at fortælle Git om, at det var en rename (og altså ikke en række sletning og tilføjelser, som det ellers godt kunne ligne), så tænkte jeg, at det kunne være lige meget - projektet er jo i sin spæde opstart, så tabet af historik er bestemt til at overse. Så jeg committede det bare, som det var.

Stor var min overraskelse, da jeg nu ser mit commit beskrevet af Git bl.a. på flg. måde:


Wow! Git har altså opdaget, at der var tale om en rename udfra det forhold, at filerne ligner hinanden; og den har ved samme lejlighed set igennem fingre med, at de ikke var helt ens (pakkenavnet var jo netop opdateret).

"Snedigt", tænker jeg, "den har regnet det ud i forbindelse committet", men så er det, at jeg kigger på commithistorikken på git-hub: der står det som sletninger og tilføjelser (se evt. her). Git-hub er altså ikke nær som snedig som min lokale Git. Men alt er ikke tabt, for under "blame" kan man se, at også git-hub kan spore ændringer på tværs af renames (se evt. her). Det gjorde så lige min antagelse om, at det var noget, som blev regnet ud på committidspunktet, ganske usandsynlig.

Derfor graver jeg lidt mere i det, og det viser sig sandelig, at det er korrekt - der er intet "rename" begreb i Git; og det er en design-feature. Man kan se her, hvordan Linus Torvalds argumenterer for, at man skal tracke indhold fremfor identitet - og her, hvor han illustrerer en yderligere fordel ved konceptet med et eksempel om en fil, der er blevet splittet op i to (begge links har jeg fundet på Wikipedia artikel om Git - søg efter "rename" på siden for nemt at finde det relevante afsnit).

Hvis det virker, så er det altså smart - og det ser ud til at virke! Det virker dog klart bedste, hvis man har disciplin nok til at holde sine refactorings for sig selv, så de ikke bliver blandet sammen med øvrige ændringer ... og det er i grunden heller ikke så dumt.

torsdag den 16. april 2009

Kryb og kravl

Det er vist ved at være et stykke tid siden, at jeg sidst har skrevet om foto, og det må der straks rettes op på med et par insekt billeder fra påsken.

Først en lille mariehøne, som det vrimler med lige nu:

Fra Makro


Og derefter en spøjs fætter, som jeg har formået at fange i fri flugt (der er også nogle lidt mere klassiske billeder af denne fætter i albummet):

Fra Makro


Jeg er faktisk ret stolt af, at det er lykkedes mig at fange et insekt i fri flugt, og det skyldes, at man virkelig har oddsene imod sig; skarphedsdybden måles under gode forhold i millimeter, som man kan se af dette billede af en bille (bemærk hvor lidt af træet, som er skarpt):

Fra Makro


Hvis der er nogen, som kan identificere de to sidstnævnte insekter, så sig frem; jeg har ikke lige kunnet finde dem.

onsdag den 18. marts 2009

Tanker på vejen

Jeg har fået kørt en del i bil på det seneste, og der har jeg tillagt mig en lidt pudsig vane. Min bil blev i sin tid købt som fabriksny, men det er efterhånden et stykke tid og over 100.000 km siden. Dens alder (og pris) gør, at den har en slags kørecomputer - man kan se flere forskellige oplysninger, som køretid, gennemsnitshastighed og brændstofforbrug - men i modsætning til de nyere og dyrere biler, så kan man ikke se det hele på en gang inkl. 6 forskellige radiostationer; man er nødt til at vælge at vise en enkelt af dem, og det inkluderer uret.

Og her er så det pudsige: Hvis jeg lader den stå på at vise, hvad klokken er blevet, så kommer jeg til at fokusere helt vildt meget på, om jeg nu også når frem i tide. Og derfor kommer jeg nemt til at køre langt mere aggressivt end jeg egentligt bryder mig om. Den anden ting, som jeg kan konstatere er, at selvom jeg kører en af tre-fire faste ruter hver dag, så er jeg virkelig dårlig til at regne ud, hvad der er realistiske tider for de forskellige dele af strækningen.

For sjov skyld prøvede jeg så at slå computeren over på at vise det aktuelle brændstofforbrug, og det havde den stik modsatte effekt: Her kom jeg til at køre fuldkommen "morfar"! Igangsætninger skete nu meget laaaangsooomt, for jeg kunne ikke klare at se det faktum i øjnene, at forbruget er astronomisk højt i de små gear. En anden effekt var, at jeg nok lå nok forrest i flere overhalingskøer end godt var.

Derefter slog jeg kørecomputeren over på at vise mit gennemsnitsforbrug over de seneste 100km, og det er faktisk her, hvor jeg har det bedst med at køre. Dels fokuserer jeg slet ikke på tiden - jeg kommer frem, når jeg kommer frem, og er det for sent, så er det nok fordi, at jeg tog for sent afsted. Og dels, så tænker jeg stadig over, hvordan jeg kører, men uden at det tager hele opmærksomheden. Jeg husker at se fremad og at motorbremse, når det er muligt, men jeg kører på motorvejen i god fart, og jeg får min overhalinger gjort grundigt - for det er nemlig ikke noget, som betyder noget i det store billede.

Og hvad er så pointen i det? Tjo, det er såmænd, at det er det store billede, som tæller, og så skal man passe på, at man ikke måler for tit undervejs. Man kan godt have fokus på at få løst alle delopgaver til tiden, men det risikerer nemt at medføre en dårlig udførelse - man kommer nok frem, men man kommer bestemt ikke sikkert frem. Man kan også have fokus på, at få løst alle delopgaver i samme kvalitet, men så kommer man nemt til at overgøre det. Det bedste er, at fokusere på det samlede resultat, for nogle steder skal man gøre sig umage, og nogle steder kan man have mere fart på.

Tænk på det, når I næste gang står omkring en scrumtavle og går i kollektiv panik over, at der måske mangler et par timer en enkelt dag, eller der er en enkelt opgave, som er gået over estimatet - det er det store billede, som tæller. Og hvis man vil nå frem i tide hver gang, så er det måske vigtigere at kende sin egen hastighed, så man kan komme afsted i tide hver gang, end det er at kende alle sine mellemtider, for at kunne træde lidt hårdere på speederen de dage, hvor myldretiden driller - det har alligevel kun meget begrænset effekt.

onsdag den 11. marts 2009

Hej, venner!

Ude til ... øhm, altså den side, hvor man starter med at læse, og "Q", "A" og "Z" sidder på de fleste tastaturer (ja, ja, jeg kan ikke kende forskel på højre og venstre - og hva' så!?) ... og så lidt nede, der har jeg anbragt en dims, hvor man kan skrive sig på, hvis man læser denne blog fast.

Det er egentlig en skør ide, og jeg er ikke sikker på, at den bliver siddende der, for dels er der nogle programmører med en firecifre IQ, som har lavet super geniale programmer til at give et godt gæt på antallet af faste læsere på en blog som denne, og lad os bare side, at 4 bits er rigeligt - og dels så kan jeg sådan set godt forstå, hvis man ikke lige har lyst til at udstille, at man synes at det jeg skriver er værd at holde øje med.

...men nu er den der, som alternativ til at skrive en kommentar eller sende mig en mail.

søndag den 8. marts 2009

Udvidbart sprog

Som de trofaste læsere allerede må have fornemmet, så er jeg så småt ved at kigge på Scala, og nedenfor er et eksempel på, hvor udvidbar sproget er:
   1:package control
2:
3:object ControlMail extends repeatable {
4: def main(args: Array[String]): Unit = {
5: repeat(5) {
6: println("Hello, World!")
7: }
8: }
9:}

Bemærk repeat konstruktionen i ln. 5: Den gør hvad man forventer, nemlig skriver fem linier med "Hello, World!"

"Ja, ja", vil man nok tænke ved første øjekast, "en konstruktion til at gentage noget et antal gange; hvor smart er det lige?". Ikke særligt, vil jeg medgive, men det er sådan set heller ikke det snedige. Det snedige er, at den konstruktion slet ikke findes i sproget - jeg har nemlig selv lige lavet den til lejligheden:
   1:package control
2:
3:trait repeatable {
4: def repeat(times: Int)(block: => Unit) {
5: for(i <- 1 to times) {
6: block
7: }
8: }
9:}

...og det synes jeg faktisk er ret snedigt!

onsdag den 18. februar 2009

Kærlighed ved første blik

Jeg tror, at jeg er blevet en lille smule forelsket. Det var sådan set nok det, som man kalder "kærlighed ved blik", for det var tydeligt allerede fra starten af, at vi tænkte på samme måde. Jeg har nemlig fundet et nyt program!

Det er faktisk et ret grimt program - der er ingen runde hjørner eller skinnende knapper med metallook. Og så alligevel, for det er helt klart lavet til at blive brugt, og får derfor sin egen funktionelle æstestik ... lidt ligesom en entreprenørmaskine, som kun fås i en farve (gul!), og hvor der ikke er levnet megen plads til gejl og pjat, men som alligevel er smuk på sin egen fascinerede måde.

Og hvad er det så for et program. Jo, det er den grafiske brugerflade, som kommer med git - aka. git-gui. Se selv:



Kan vi ikke blive enige om, at det ikke ligefrem er et program, som gør sig forhåbninger om at vinde nogen form for design-priser?

Men lad os kigge lidt på det: Når jeg arbejder, så starter jeg selvfølgelig med at lave et antal ændringer, og derefter laver jeg en liste over ændrede filer, som jeg så kører en diff på en ad gangen. Her bestemmer jeg med for, hvilke ændringer, som jeg vil have med i committet - og egentlig ret ofte opdager jeg, at jeg ikke var helt færdig: der er ofte noget, som kan gøre lidt bedre eller pænere. Og så tager jeg lige en iteration eller to mere.

Kast nu et blik på screendumpet. I panelet med den røde top er en liste over alle de filer, som er ændrede - eller nye - i mit arbejdsområde. Det var lige første trin, som jeg fik forærende. I panelet med den gule top, kan jeg se diff for den valgte fil - og det var andet trin. Efterhånden som jeg arbejder mig igennem filerne, så kan jeg klikke på ikonet ud for filnavnet, og så smutter de lige ned i panelet med den grønne top, som er en liste af de ændringer, der er planlagt til næste commit; og det er noget, som jeg normalt selv skal holde styr på. Nederst til højre er en god editor til at skrive commitkommentaren i - og selvfølgelig er den fremme hele tiden, så man kan udfylde kommentaren imens man reviewer sine ændringer, og ikke som det er for mig pt., nemlig at jeg må tage noter for mig selv undervejs, inden jeg til sidst får lov at skrive en kommentar.

Eller med andre ord: her er et værktøj lige efter mit hovede - alle de nødvendige dele er placeret nemt og overskueligt, lige inden for rækkevidde, lige hvor man har brug for det. Der er tænkt på det hele. Skønt!

Allerede her var jeg sådan set solgt, men bemærk så lige en ekstra lille detajle (det kan godt være, at du skal klikke på billedet for at se det i stor størrelse): filen Method.scala er nævnt både under unstaged og staged! Det er fordi, at jeg har rettet videre i den efter at jeg stagede den til commit først gang - og det diff, som jeg kan se under unstaged, er det, som er sket siden seneste staging - og det, som jeg kan se under staged er det, som er sket imellem seneste commit og seneste staging (eller det, som kommer med i dette commit, hvis ikke jeg gør yderligere). Det er en rigtig god lille bonus.

...og husk så på, at git er et distibueret versionsstyringssystem - når jeg engang committer, så er det kun imod mit lokale repository - for at det kommer videre, så skal det enten pushes videre af mig, eller pulles af andre.

onsdag den 11. februar 2009

Kloner og gists

Jeg må tilstå: jeg har en temmelig underlig interesse, nemlig versionsstyring og versionsstyringssystemer. Jeg har tidligere skrevet lidt forskelligt om emnet, men på det seneste er jeg så småt begyndt at interessere mig for Git.

Git i sig selv er mange ord værd, men det er faktisk ikke det, som jeg vil skrive om her; mest fordi at mine erfaringer indtil videre er noget begrænsede (for en knap så kort oversigtsartikel om git, vil jeg henvise til Wikipedia).

Næh, det som jeg har på hjerte er, at jeg har fundet git-hub, som er et site, hvor man kan få hostet sine git-repositories. Og hvis man er villig til at dele sin kildetekst med alle (det hedder vist nok "Open Source"), så koster det gratis.

Det, som man giver andre ret til, er at se hele versionshistorikken, og at starte deres egen variant - det hedder meget passende "kloning" - men ikke til at committe direkte til ens eget repository. Klassisk set er det, at få "gaflet" (forked) et projekt noget af det, som har givet anledning til de fleste søvnløse nætter og de største ord-krige, men her er det faktisk noget, som ikke alene er indbygget i både git og git-hub - det er faktisk noget, som man aktivt opfordrer til. For den bagvedliggende tanke er ikke, at vejene skal skilles for evigt, men i stedet at man for en kort bemærkning lige afsøger området omkring den slagne sti, for så at vende tilbage igen med det gode, som man måske fandt. For rettelser fra kloner kan snildt indarbejdes i det oprindelige repository, og herved har man nærmest vendt begrebet på hovedet: hvis kloning er noget man gør hyppigt nok, så er det en ting, som man kan udnytte positivt.

Og der er ingen der siger, at den oprindelige vej, er den bedste, så måske vil de fleste i stedet vælge det, som oprindeligt var en afstikker, hvorved det så bliver hovedvejen. Det vil i sandhed være realisering af begrebet "shared source": ingen ejer kildeteksten; og alle har lige ret til at komme med deres bud på fremtiden.

Nå, men inden dette bliver alt for lomme-filosofisk, så vil jeg lige pege på en sjov lille ting på git-hub, som de kalder for "gists" - det er en slags mini-repository, eller en slags offentligt klippebord for filer med fuld versionshistorik. Om det kan bruges til noget i praksis, ved jeg ikke helt, men jeg måtte simpelthen prøve det af, så jeg har oprettet mit eget lille gist - ikke noget specielt, bare et lille fragment fra mine første eksperimenter med Scala og Xml. Men kom og leg med, hvis du har lyst - det er det, som git-hub går ud på!