Kapitel 5. Programmørens værktøjskasse

En programmørs værktøjskasse bør indeholde:

Derudover kan det være praktisk med:

Og hvis du programmerer i C, C++ eller C#, vil du temmelig sikkert også få brug for en læksøger. Det kan for eksempel være efence (Afsnit 5.9).

Og det ideelle ville selvfølgelig være hvis man kunne få hele sin værktøjskasse integreret i ét udviklingsmiljø. Emacs (Afsnit 5.14) er nok det mest populære integrerede udviklingsmiljø til Linux. I standardopsætningen snakker Emacs fint med CVS og en utroligt bred samling oversættere, samtidig med at det giver syntaksfremhævning og sprogspecifikke genvejstaster til langt de fleste programmeringssprog. Det at Emacs grundlæggende er et tekstbaseret program, generer vist en del mennesker, men på den anden side kan Emacs bruges til så meget at man hurtigt kommer til at undre sig over hvordan man kan klare sig uden. Hvis du har valgt at programmere i C++, er KDevelop (Afsnit 5.13) et andet muligt valg af integreret udviklingsmiljø. KDevelop er et decideret grafisk udviklingsmiljø og ser en del smartere ud end Emacs. Desværre er det begrænset til programmering i C++. Anjuta (Afsnit 5.12) er et nyt integreret grafisk udviklingsmiljø. Anjuta kan håndtere adskillige programmeringssprog, men dog ikke nær så mange som Emacs (det er vist også en svær opgave).

5.1. Concurrent versioning system (CVS)

Concurrent versioning system (CVS) er et versionsstyringssystem. Dette er godt nok en programmeringsbog, men i virkeligheden bør man bruge et versionsstyringssystem til alle projekter der varer længere end et par dage eller har flere end en enkelt deltagende forfattere. Versionsstyringssystemets opgave er at holde styr på de forskellige udgaver en fil har eksisteret i, hvilke ændringer der er foretaget, hvorfor, og af hvem. Der holdes styr på dette i et centralt fælles CVS-arkiv, hvor alle ændringer registreres. En af de ting der gør CVS til noget særligt blandt versionsstyringssystemer, er at det tillader at flere forfattere samtidig arbejder på de samme filer. Så længe der ikke er flere der retter i de samme linjer, vil CVS flette de forskellige ændringer sammen efterhånden som de bliver lagt ind i det fælles arkiv.

Versionsstyringssystemer som CVS er en nødvendighed for udviklingsprojekter der – som for eksempel Linux – foregår spredt rundt omkring i verden. Antag at et firma eller universitet har behov for at kunne arbejde med udvikling af programmer på kryds og tværs af geografi hvor al kommunikation skal ske via internettet. To spørgsmål melder sig hurtigt til systemadministratoren: Hvad med sikkerheden, og hvordan kan man styre softwareudviklingsprocessen, når der er mange mennesker involveret, på en sådan måde at man kan lave udgivelser som altid kan genskabes (til serviceformål), mens man samtidigt videreudvikler, og dermed har behov for at kunne bakke tilbage gennem opdateringerne i tilfælde af fejl.

De fleste danske og udenlandske softwarefirmaer har foretaget deres udvikling baseret på udvikling i lokale netværk. Med den fortsatte ekspansion af udviklingen af internettet og med den fortsatte udvikling hvor begreber som "hjemmearbejdsplads" og "distancearbejde" dukker op oftere og oftere, må det forventes at softwareudviklingsfirmaer allerede er i gang med og i endnu højere grad vil foretage udviklingen af software baseret på utroligt mange computere bundet sammen af internettet. Dette stiller store krav til de versionsstyringssystemer der benyttes.

Styring af softwareprojekter er svært! Specielt svært bliver det når mange arbejder på den samme kildetekst, og hvor samtidigt kommunikationen mellem projektdeltagerne er ringe eller besværlig. De krav der må stilles til versionsstyringssystemerne i sådanne projekter, er at alle ændringer let skal kunne tilgå andre på projektet, alle ændringer skal kunne hives ud af kildeteksten igen, og man skal kunne se hvem der har lavet hvad på hvilket tidspunkt.

Når man en gang har prøvet at være to eller flere som fysisk retter i samme kildetekst uden at man bruger et versionsstyringssystem, er det indlysende at denne form for samarbejde er uproduktiv. På sådanne præmisser er megen kommunikation og dermed megen uproduktiv tid nødvendig hvis det skal være muligt at opnå et tilfredsstillende resultat. En mulighed for at øge produktiviteten er at gøre brug af et versionsstyringssystem.

CVS er et multi-platform versionsstyringssystem som har alt det man kan ønske sig af et sådant system. Det er frit tilgængeligt under GNU-licensen (GPL). Du kan læse mere om CVS på http://www.linux.ie/articles/tutorials/managingaccesswithcvs.php, http://www.cvshome.org/docs/blandy.html, http://www.ibiblio.org/mdw/REF/CVS-BestPractices/html/index.html eller http://cvsbook.red-bean.com/cvsbook.html.

CVS er et forholdsvis nyt versionsstyringssystem, og dets håndtering af konflikter mellem forskellige udvikleres arbejde regnes for at være unik.

5.1.1. CVS' funktionalitet

CVS bruges til at gemme den historie som ens kildetekster (af den ene eller den anden slags) gennemløber. Grundprincippet i CVS er at alle brugere har deres egen lokale kopi af kildeteksten som kan modificeres uafhængigt af andre brugere. Dette kan ske med brugere på samme maskine eller på maskiner placeret vilkårligt langt fra hinanden. Når ens personlige kopi af kildeteksten er stabil og fungerende, kan alle de opdaterede filer lægges ind i CVS-arkivet igen, eventuelt først efter at være blevet flettet sammen med andre udvikleres ændringer af de samme filer. På denne måde kan man uden at begrænse andre i deres arbejde udføre meget arbejde (lang tids arbejde og/eller mange ændringer) på sin lokale kopi af kildeteksten, uden alvorlig risiko for at der opstår problemer når rettelserne lægges ind i det fælles arkiv.

CVS understøtter at arkivet (samlingen med versionsstyringssystemets information, inklusive kildeteksterne) kan gøres tilgængelig på nettet uden at man behøver at montere diske fra andre maskiner. Almindeligvis anvendes ssh til at håndtere sikker udveksling af data mellem programmørernes maskiner og det centrale arkiv.

CVS udmærker sig ved at have et sæt af kommandoer til at pakke distributionen ud, at opdatere ens egen distribution med andres ændringer, at lægge ens egne ændringer i arkivet, at lave sideløbende grene af udviklingen af produktet, at samle sideløbende grene af udviklingen, at hente information om historien af ændringer osv.

Det er værd at bemærke at tekstbehandlingsprogrammet Emacs automatisk vil bemærke det hvis du redigerer filer der ligger i et CVS-arkiv. Det vil så vise en ekstra menu der giver adgang langt de fleste af de daglige CVS-funktioner. Fra Emacs kan man bl.a. lægge filer ind i CVS, hente senere udgaver af de enkelte filer, og få sammenlignet forskellige udgaver af samme fil.

5.1.2. Daglig brug af CVS

Hvis vi går ud fra at andre har taget sig af at lægge filerne fra et projekt du skal til at arbejde på i et CVS-arkiv (se Afsnit 5.1.3, hvis du selv skal gøre det), er det forholdsvis enkelt at komme i gang. Du skal blot kende CVS-arkivets adresse og projektets navn i arkivet. De første tre af de følgende eksempler viser hvordan du går i gang med at arbejde med filer der ligger i et CVS-arkiv, afhængigt af hvilken form for adgang du har til det (Eksempel 5-1, Eksempel 5-2 og Eksempel 5-3). Dernæst følger eksempler der viser hvordan du opdaterer din personlige kopi af arkivet (Eksempel 5-4), hvordan du lægger rettede filer tilbage i det fælles arkiv (Eksempel 5-5), hvordan du tilføjer filer (Eksempel 5-6), hvordan du sletter filer (Eksempel 5-7), og hvordan du lægger en rettet fil tilbage i det fælles arkiv direkte inde fra Emacs (Eksempel 5-9).

Eksempel 5-1. Gå i gang med at bruge et lokalt CVS-arkiv


hven% cvs \
-d /usr/local/CVSROOT checkout webspell

  • "-d /usr/local/CVSROOT" betyder at det CVS-arkiv projektet skal hentes fra, ligger i kataloget /usr/local/CVSROOT på den maskine du arbejder på.

  • checkout betyder at du vil have oprettet en kopi af et projekt der ligger i det førnævnte CVS-arkiv.

  • Og endelig er "webspell" navnet på det projekt vi vil have en kopi af.

Eksempel 5-2. Anonym brug af et CVS-arkiv på nettet


hven% echo "update -dP" >> ~/.cvsrc
hven% cvs -d :pserver:anonymous@cvs.sf.net:/cvsroot/tuxpaint login
CVS password: (enter)
hven% cvs -d :pserver:anonymous@cvs.sf.net:/cvsroot/tuxpaint checkout tuxpaint
U tuxpaint/Makefile
U tuxpaint/README.txt
U tuxpaint/data/brushes/round_03.png
...
hven% 

Den første kommando er ikke strengt nødvendig, men sørger for at cvs automatisk henter nye underkataloger (og ikke kun dem man allerede har), når man senere opdaterer sin lokale kopi af CVS-arkivet.

Den næste kommando sørger for at »logge ind« på CVS-serveren. Det er kun noget man behøver gøre en gang for anonyme adgang til et CVS-arkiv. Anonym adgang til et CVS-arkiv fungerer normalt med en blank adgangskode, så det er nok at taste <enter>, når cvs skriver »CVS password: «.

Den sidste kommando er den der henter en lokal kopi af CVS-arkivet ned, så du kan arbejde med filerne (også uden at have netforbindelse til CVS-serveren).

  • "-d :pserver:anonymous@cvs.sf.net:/cvsroot/tuxpaint" betyder at det CVS-arkiv projektet skal hentes fra, ligger i kataloget /cvsroot/tuxpaint på maskinen "cvs.sf.net", og at du vil hente det som en anonym bruger.

  • checkout betyder at du vil have oprettet en kopi af et projekt der ligger i det førnævnte CVS-arkiv.

  • Og endelig er "tuxpaint" navnet på det projekt vi vil have en kopi af. I dette konkrete tilfælde er det oversættelser af KDE (menutekster og brugsanvisninger) til forskellige sprog.

Eksempel 5-3. Brug af et CVS-arkiv på nettet over SSH


hven% export CVS_RSH=ssh

Denne kommando sætter en variabel der fortæller cvs at kommunikation over nettet skal kunne ske med SSH-protokollen (der er krypteret og dermed sikrer mod aflytning af adgangskoder og data). Bemærk at variablen også skal være sat når du senere vil opdatere din kopi af projektet eller vil lægge en rettet fil ind i CVS-arkivet. Det kan du hurtigt sikre med kommandoen echo "export CVS_RSH=ssh" >> ~/.zshrc.


hven% cvs \
-d tyge@cvs.sslug.dk:/usr/local/CVSROOT checkout linuxbog

  • "-d tyge@cvs.sslug.dk:/usr/local/CVSROOT" betyder at det CVS-arkiv projektet skal hentes fra, ligger i kataloget /usr/local/CVSROOT på maskinen "cvs.sslug.dk", og at du vil hente det som brugeren "tyge".

  • checkout betyder at du vil have oprettet en kopi af et projekt der ligger i det førnævnte CVS-arkiv.

  • Og endelig er "linuxbog" navnet på det projekt vi vil have en kopi af. I dette konkrete tilfælde er det hele bogserien "Linux – Friheden til at vælge".

Eksempel 5-4. Opdatér din personlige kopi af et CVS-arkiv


hven% cd webspell/
hven% cvs update -d

  • Du skal stå i kataloget med din lokale kopi af CVS-arkivet for at kunne opdatere filerne. Ovenfor bliver det gjort med kommandoen cd webspell.

  • Argumentet "update" betyder at du vil have opdateret den personlige kopi af et CVS-arkiv der allerede ligger i det katalog du står i. Argumentet "-d" gør at også nye underkataloger bliver opdateret. Tilføj yderligere "-C" hvis eventuelle egne rettelser skal overskrives af CVS-arkivets version.

Eksempel 5-5. Læg en rettet fil tilbage i det fælles CVS-arkiv

Vi antager nu at vi som efter forrige eksempel står i kataloget med den personlige kopi af CVS-arkivet, og at vi har rettet en HTML-syntaksfejl i filen tjek.php.


hven% cvs commit \
-m 'validator.w3.org brokkede sig' tjek.php

  • "commit" betyder at du vil kopiere din rettede udgave af en fil ind i det fælles CVS-arkiv.

  • "-m 'validator.w3.org brokkede sig'" betyder at rettelserne i CVS-arkivets logbog skal have kommentaren "validator.w3.org brokkede sig".

  • Og endelig er "tjek.php" navnet på den fil du har rettet og vil kopiere ind i det fælles arkiv.

Eksempel 5-6. Tilføj en ny fil til et CVS-arkiv

Hvis vi nu har skrevet en ny fil ved navn "tak.html", og den ligger sammen med vores personlige kopi af projektet, kan vi tilføje den med kommandoerne:


hven% cvs add tak.html
hven% cvs commit -m 'lidt almindelig høflighed' tak.html

  • "add" betyder at du vil føje din rettede udgave af en fil til det fælles CVS-arkiv.

  • Og endelig er "tak.html" navnet på den fil du har skrevet og vil føje til det fælles arkiv.

  • Efter at "tak.html" er blevet føjet til arkivet, bruges "cvs commit" til at aktivere tilføjelsen.

Eksempel 5-7. Fjern en fil fra et CVS-arkiv

Vi har nu eksperimenteret lidt med en fil "tjek-eksp.php" og fundet ud af at der alligevel ikke er brug for den i projektet, så vi vil fjerne den fra den synlige del af CVS-arkivet (arkivet husker alle ændringer, så du vil stadig kunne gå tilbage til en udgave hvor filen fandtes). Det klares med kommandoerne:


hven% rm -f tjek-eksp.php
hven% cvs remove tjek-eksp.php
hven% cvs commit -m 'det gik ikke' tjek-eksp.php

  • CVS vil ikke fjerne en fil fra arkivet hvis du stadig har en kopi af den i din personlige kopi af CVS-arkivet, så vi starter med kommandoen rm -f tjek-eksp.php der fjerner filen fra kataloget.

  • "remove" betyder at du vil fjerne filen fra det fælles CVS-arkiv.

  • Og endelig er "tjek-eksp.php" navnet på den fil der skal fjernes fra det fælles arkiv.

  • Efter at "tjek-eksp.php" er blevet slettet fra arkivet, bruges "cvs commit" til at aktivere sletningen.

Eksempel 5-8. Fjern et helt katalog i et CVS-arkiv

CVS er ikke ret god til at slette kataloger. Måden at håndtere sletning af hele underkataloger er at slette alle filer i kataloget og derefter køre cvs update -d -P. Her vil -d gøre at kataloger opdateres med, og -P er at fjerne ("prune") tomme kataloger.

I nedenstående eksempel fjerner vi mit_katalog som er et underkatalog af projekt.


hven% cd mit_katalog
hven% ls
CVS      Makefile    prg.c      prg.h
hven% rm prg.c prg.h Makefile
hven% cvs remove prg.c prg.h Makefile
hven% cvs commit -m "Farvel til gamle filer"
hven% cd ..
hven% cvs update -d -P

Eksempel 5-9. Læg en rettet fil tilbage i det fælles arkiv direkte inde fra Emacs

Hvis du har rettet i en fil fra et CVS-arkiv i Emacs, kan du lægge den rettede fil tilbage i arkivet direkte inde fra Emacs. Det kan for eksempel være praktisk hvis du løbende vil lave sikkerhedskopier af en rapport du er i gang med at skrive, så du uden problemer kan gå tilbage til tidligere udgaver af filen. For at lægge filen tilbage i arkivet taster du først Ctrl-X V V. Hvis filen ikke allerede er gemt, får du nu mulighed for det. Dernæst kommer der et vindue i Emacs hvor du kan indtaste en bemærkning om de seneste ændringer. Når du har indtastet ændringerne, taster du Ctrl-C Ctrl-C, og så er filen lagt tilbage i CVS-arkivet.

Hvis forbindelsen til CVS-arkivet går over en SSH-forbindelse, vil du blive bedt om løsen eller adgangskode både før og efter du indtaster bemærkningerne til ændringerne.

Hvis det er en ny fil du vil oprette i CVS-arkivet, er det først anden gang du taster Ctrl-X V V at filen rent faktisk bliver lagt ind i arkivet. I første omgang bliver filen blot registreret (svarer til cvs add).

5.1.2.1. Konfliktløsning ved "dobbelt-opdatering"

Hvis der er konflikter mellem en fil i din personlige kopi af CVS-arkivet og den samme fil i det fælles CVS-arkiv fordi en anden bruger i mellemtiden også har opdateret filen, så vil du skulle flette de to opdateringer sammen før du kan lægge dine rettelser ind i det fælles arkiv. Det gøres ved at du først "opdaterer" din lokale kopi af filen (cvs update <filnavn>). CVS vil så markere forskellene mellem de to udgaver, så du i dit tekstbehandlingsprogram kan vælge hvilke udgaver af rettelserne du foretrækker. Når du har valgt mellem rettelserne og i øvrigt tjekket at filen er i orden, kan du lægge den sammeflettede opdatering ind i det fælles CVS-arkiv på sædvanlig vis (cvs commit <filnavn>).

5.1.2.2. Gamle udgaver af filer i CVS-arkivet

Hvis en fil er blevet rettet i en helt forkert retning, er det muligt at hente en gammel udgave af filen ud af det fælles CVS-arkiv og arbejde videre ud fra den. Det gøres med kommandoen cvs update -r <udgavenummer> <filnavn>.

5.1.2.3. Sætte huskemærker (tags) i CVS

Det kan være meget praktisk at kunne sætte et mærke på en fil for at man til hver en tid kan gå tilbage til netop den version af filen. For at sætte et mærke (engelsk "tag") kører man cvs tag MÆRKE fil_liste hvor MÆRKE er et navn (desværre må man ikke anvende mellemrum) a la efter_indfletning_af_SSLUG_kode eller foer_Peters_sommerferie.

Hvis man har brug for at gå tilbage til et givet mærke køres cvs update -r MÆRKE. Samme teknik anvendes også til at håndtere forskellige grene af koden.

5.1.2.4. Filers status

Enhver kan og bør principielt tjekke status for de enkelte filer før opdateringer bliver lagt ind i det fælles arkiv. Det gøres med kommandoen cvs status <filnavn>. CVS vil så vise udgavenummeret for den fil du har liggende, såvel som udgavenummeret for den fil der ligger i det fælles arkiv.

Anvend tilsvarende cvs status -v <filnavn> til at få endnu mere information om filen inklusive forgreninger.

Tip: En meget effektiv måde at få styr på status for alle filer er at anvende cvsstat eller cvschk det kan findes på http://cvs.sslug.dk/cvs2html/.

5.1.2.5. Logbogen

Hver gang du lægger ændringer ind i det fælles CVS-arkiv, kan du skrive en besked i logbogen om hvorfor du har lavet de ændringer. I Eksempel 5-5 bruger vi kommandolinjeflaget "-m" til at angive teksten til logbogen. Hvis du ikke bruger "-m"-flaget, vil CVS i stedet starte det tekstbehandlingsprogram systemvariablen "EDITOR" peger på, så du kan skrive teksten der.

Hvis du på et tidspunkt vil se hvad der for eksempel står i logbogen om filen tjek.php, bruger du kommandoen:


hven% cvs log tjek.php

Den vil give dig en liste med de forskellige udgaver af filen, hvem der har lavet ændringerne, og hvad der står om dem i logbogen. Selve ændringerne bliver dog ikke vist.

5.1.2.6. Forskelle mellem forskellige udgaver af en fil

Logbogen (cvs log) viser ikke selve ændringerne i en fil. For at se dem skal man bruge tilvalget diff. Den helt enkle brug af tilvalget diff er:


hven% cvs diff tjek.php
der viser forskellene mellem den udgave af tjek.php der ligger i CVS-arkivet og den der arbejdes med.

Hvis man vil se forskellene mellem to udgaver af en fil i CVS-arkivet, bruger man tilvalget -r til at identificere de to udgaver:


hven% cvs diff -r 1.21 -r 1.22 vaerktoej-cvs.sgml

5.1.2.7. CVS med SSH på en alternativ port

Hvis CVS-arkivet ligger på en maskine der står bag en dørvogter, eller hvis SSH af andre mystiske omstændigheder ikke kører på port 22, er det lidt sværere at få cvs til at kontakte arkivet. Problemet kan klares ved at man fortæller SSH hvilken port SSH kører på uden at fortælle CVS det. Det gør man i SSH's opsætningsfil $HOME/.ssh/config hvor man for eksempel kan tilføje:


Host cvs.saltholm.oresund.dk
   Hostname skatkammeret.saltholm.oresund.dk
   Port     4444
hvilket betyder at når CVS -- og dermed SSH -- bliver bedt om at kontakte "cvs.saltholm.oresund.dk" (underforstået at det er på port 22), så vil SSH i virkeligheden kontakte "skatkammeret.saltholm.oresund.dk" på port 4444.

Nu kan du altså kontakte CVS-arkivet bag dørvogteren ganske som i eksempel Eksempel 5-3:


hven% export CVS_RSH=ssh
hven% cvs \
-d cvs.saltholm.oresund.dk:/usr/local/CVSROOT checkout hemmeligt_projekt

5.1.3. Opsætning af CVS

Endelig skal nævnes hvordan man opretter et fælles CVS-arkiv, og hvordan man lægger en samling filer ind i det fælles arkiv.

5.1.3.1. Oprettelse af et CVS-arkiv

Hvis du ikke allerede har adgang til et CVS-arkiv, du kan lægge dine filer ind i, må du oprette et. Hvis du har systemadministratorrettigheder bør du oprette et katalog med navnet /usr/share/CVSROOT og lægge det der. Alternativt kan du for eksempel lægge det i $HOME/.CVSROOT. Det er vigtigt at alle der skal kunne lægge filer ind i og rette filer i CVS-arkivet, har adgang til at skrive i kataloget. Vi går her ud fra at de alle er med i brugergruppen "cvsusers" (se systemadministratorbogen for information om brugergrupper). CVS-arkivet oprettes med kommandoen:


hven% cvs -d $HOME/.CVSROOT init

Når en bruger vil oprette sin egen arbejdskopi af CVS-arkivet, skal han/hun blot kende navnet på det katalog du valgte at lægge det fælles centrale CVS-arkiv i (husk at "$HOME" refererer til dit hjemmekatalog; echo $HOME/.CVSROOT vil give dig det fulde navn på det katalog der blev brugt i ovenstående eksempel). Se i øvrigt eksemplerne Eksempel 5-1, Eksempel 5-2 og Eksempel 5-3 for flere detaljer. Vi kommer ikke ind på hvordan man giver anonym adgang til et CVS-arkiv her.

5.1.3.2. Opret et projekt i CVS-arkivet

Lad os komme videre. For at du kan lægge dine filer i CVS for første gang, skal du flytte dig til hovedbiblioteket for kildeteksten (vi antager at det – og projektet – hedder webspell, og at du oprettede CVS-arkivet som beskrevet i forrige afsnit) og importere filerne, fjerne filtræet og til sidst trække det ud af CVS-arkivet igen (denne gang med udgavehåndteringsinformation):


hven% cd webspell
hven% cvs -d $HOME/.CVSROOT import webspell Tyge foerste-udgave-i-cvs
hven% cd ..
hven% mv webspell webspell-før_cvs
hven% cvs -d $HOME/.CVSROOT checkout webspell

Tyge er et felt der af CVS kaldes "vendor tag" (leverandørmærke), og foerste-udgave-i-cvs er et felt der af CVS kaldes "release tag" (udgavemærke).

Det kan også nævnes at en række ekstra værktøjer fås til CVS, se http://freshmeat.net/ under CVS. Et af disse er cvs2html der findes fra http://cvs.sslug.dk/cvs2html/. cvs2html anvendes til at reformattere den loginformation der er skrevet ind for hver fil ved "cvs commit", til HTML-filer. For internetbaserede samarbejdsprojekter er dette virkeligt smart.

Det tager et par timer at komme ind i denne måde at arbejde på, men ved alle programmerings- eller skriveprojekter i øvrigt med mere end en person vil CVS tjene dette overhead ind i hundredefold.

5.1.3.3. Få breve med log-meddelelser ved cvs commit

Når flere folk arbejder sammen på et software-projekt, er det nødvendigt at man nemt kan se hvad andre personer har ændret i filerne. Med cvs watch add FILNAVN vil du modtage breve når andre kører cvs commit FILNAVN, men her vil du ikke se hvad de har ændret. Du kan få en bedre føling med ændringerne ved at bruge et lille program log der følger med cvs. Med det program kan du få et brev om hvilke filer som er ændret, og du får også den log-meddelelse brugeren skrev, med i brevet. Hvis man inden for projektet holder en god stil med at skrive ordentlige log-meddelelser, så er dette super.

Lad os se på opsætningen af dette. Først skal du lave en logfil i CVSROOT-kataloget som alle deltagere i dit projekt kan læse og skrive. I det følgende skal du erstatte STI_TIL_CVS-RODEN med den fulde sti til dit CVSROOT-katalog.


hven% touch STI_TIL_CVS-RODEN/CVSROOT/commitlog
hven% chgrp PROJEKTGRUPPE STI_TIL_CVS-RODEN/CVSROOT/commitlog
hven% chmod g+rw STI_TIL_CVS-RODEN/CVSROOT/commitlog

Dernæst skal vi rode i noget af de "helligste" af cvs-opsætningen.


hven% cvs -d STI_TIL_CVS-RODEN checkout CVSROOT
hven% vi CVSROOT/loginfo
Indsæt følgende linje til sidst hvis tyge@hven.oresund.dk skal modtage breve. Er der flere som skal modtage breve, så tilføj gerne flere "-m modtager@maskine" efter hinanden:

DEFAULT /usr/share/cvs/contrib/log -m tyge@hven.oresund.dk -f STI_TIL_CVS-RODEN/CVSROOT/commitlog


hven% cvs commit -m "Man kan modtage logbeskeder per post" CVSROOT/loginfo
hven% cvs release -d CVSROOT
De sidste linjer vil regenerere CVSROOT (sted hvor CVS-opsætningen er gemt), og derefter sletter man den CVSROOT-kopi man har tjekket ud.

5.1.4. Forgreninger i udviklingen

Lad os se lidt mere på starten, da vi lavede projektet.


hven% cd MODUL_DIR
hven% cvs -d STI_TIL_CVS-RODEN import MODUL VENDOR_TAG RELEASE_TAG
Dette genererer med det samme to grene (engelsk: "branches") som man altid kan komme tilbage til.

  • 1.1.1 – VENDOR_TAG

  • 1.1.1.1 – RELEASE_TAG

Går man i gang med at tjekke filerne ud, rette og køre cvs commit, så kommer de enkelte versioner til at hedde version 1.1, 1.2, 1.3 osv.

Ofte vil alle bruge samme gren af filerne, men hvad gør man hvis man nu har brug for at kode et stykke tid på noget som lammer resten af udviklerne på samme projekt. I dette tilfælde kan man oprette en gren til dette – de andre udviklere kommer ikke til at se noget anderledes, og to adskilte udviklingsgrene kan køre.

Lad os antage at vi arbejder med et modul i CVS med navn "sslugkode" som er importeret i CVS ved at skrive cvs import sslugkode start version0. Da der ikke er nogen naturlig "vendor" sættes leverandør-tag blot til "start" og start-version til "version0".

For at skabe "gren1" ud fra hovedgrenen "version0" skriver man (uden at man nødvendigvis har koden tjekket ud):


hven% cvs rtag -b -r version0 gren1 sslugkode

Tilsvarende kunne man måske have en anden udvikler som skal arbejde samtidig på en anden gren, "gren2":


hven% cvs rtag -b -r version0 gren2 sslugkode

For at isolere sig selv i grenen "gren1" skrives:


hven% cvs -d STI_TIL_CVS-RODEN checkout sslugkode
hven% cd sslugkode
hven% cvs update -r gren1
eller direkte

hven% cvs -d STI_TIL_CVS-RODEN checkout -r gren1 sslugkode

Det normale er derefter at udvikleren retter, laver cvs commit som vanligt. Fordelen er at de andre udviklere ikke ser dette. Grenene er totalt afkoblede indtil der laves en "merge"

Hvis det skulle ske at vores udvikler fra "gren1" skal hjælpe ham som arbejder i "gren2"-grenen, så kan han lave cvs commit på egne filer og derfter skifte direkte over til "gren2":


hven% cvs update -r gren2

Endelig kan man skifte ud til hoved-sporet (komme ud af henholdsvis "gren1" og "gren2" ved at skrive:


hven% cvs update -A

5.1.4.1. Flette grene sammen igen

Antag at to udviklingsgrene som hver for sig har udviklet sig, på et tidspunkt skal flettes sammen. Du har været så smart at du kørte cvs tag TAG1 da du startede med din "gren1", og du har også gemt et mærke TAG2 ved slutningen af "gren1" – dvs. du har lige kørt cvs tag TAG2 i "gren1".

I "gren2"-grenen kan du opdatere samtlige ændringer fra "gren1"-grenen mellem TAG1 og TAG2 ved at skrive:


hven% cvs update -j TAG1 -j TAG2

Hvis man ikke var i "gren2", skal man først sikre at man er i "gren2"-grenen:


hven% cvs update -r gren2
hven% cvs update -j TAG1 -j TAG2

Der er lidt mere information om emnet på http://groups.yahoo.com/group/info-cvs/message/12246.

5.1.5. Diverse med CVS

Det kan nævnes at hvis Emacs indlæser en fil der er koblet ind i CVS, vil Emacs automatisk genkende dette og indsætte en ekstra menu, hvorfra du på enkel vis kan sende tilføjelser til den fælles database (selve ændringerne skal du ikke selv styre – det klarer Emacs og CVS).

Skal man anvende en "export" version til distribution, eller blot ikke ønsker at lave en "checkout", så er cvs export PROJEKT også en mulighed. Den henter kun filerne, men ikke CVS-informationsfilerne. Meget praktisk til at skelne mellem udgivelse af filer ("export") i forhold til udvikler-version med fuld CVS-information ("checkout").

Vi har tidligere vist at projekt/kildetekst hentes med:


hven% cvs STI_TIL_CVS-RODEN checkout projektnavn

Hvis man ser efter i projekt-katalog/CVS, så finder man der tre filer som tilhører CVS:

  • Repository indeholder projekt-navn på CVS-serveren.

  • Root indeholder CVSROOT for det pågældende projekt.

  • Entries indeholder listen over de filer og kataloger som er registreret i CVS.

Næste trick er for dem som anvender SSH til at kommunikere med CVS. Man kan få ssh til at understøtte komprimering i ~/.ssh/config:


Compression      yes
CompressionLevel 6
Men vær opmærksom på at visse servere ikke kan finde ud af at anvende komprimering, så er der uforklarlige problemer med at få forbindelse, så slå det fra.