0b10

Github lanserades 2008. Om din programvaruteknik karriär, som min, ärinte äldre än Github, då kan Git vara den enda versionskontrollprogramvaran du någonsin har använt. Medan människor ibland ryper om sin branta inlärningskurva ellerunintuitivt gränssnitt, Git har blivit allas go-to för versionskontroll. InStack Overflow 2015 utvecklarundersökning, 69,3% av de svarande använde Git, nästantvå gånger så många som använde det näst mest populära versionskontrollsystemet,Subversion.1 efter 2015 slutade Stack Overflow att fråga Utvecklare omversionskontrollsystem de använder, kanske för att Git hade blivit så populäratt frågan var ointressant.

Git själv är inte mycket äldre än Github. Linus Torvalds släppte den förstaversion av Git 2005. Även om idag yngre utvecklare kan ha svårt att ta emot en värld där termen ”versionskontrollprogramvara” inte mer ellermindre bara betyder Git, fanns en sådan värld inte så länge sedan. Det fanns många alternativ att välja mellan. Utvecklare med öppen källkod föredrog Subversion, företag och videospelföretag använde Perforce (vissa gör det fortfarande), medan theLinux-kärnprojektet berömt förlitade sig på ett versionskontrollsystem som heterbitkeeper.

några av dessa system, särskilt BitKeeper, kan känna sig bekant för en youngGit-användare som transporteras tillbaka i tiden. De flesta skulle inte. BitKeeper åt sidan, versionkontrollsystem som kom före Git fungerade enligt ett fundamentalt annorlunda paradigm. I en taxonomi som erbjuds av Eric Sink, författare till VersionControl by Example, är Git ett tredje generationens versionskontrollsystem, medan de flesta av Git: s föregångare,de system som var populära på 1990-talet och början av 2000-talet, är andra generationens versionskontrollsystem.2 där tredje generationens versionskontrollsystem distribueras är andra generationens versionskontrollsystem centraliserade. Du har nästan säkert hört Git beskrivet som ett” distribuerat ” versionskontrollsystem tidigare. Jag förstod aldrig riktigt dendistribuerade / centraliserade skillnaden, åtminstone inte förrän jag installerade ochexperimented med ett centraliserat andra generationens versionskontrollsystemsjälv.

systemet jag installerade var CVS. CVS, kort för samtidiga versioner System, varDet allra första andra generationens versionskontrollsystem. Det var också mestpopulärt versionskontrollsystem i ungefär ett decennium tills det ersattes 2000 genom Subversion. Även då skulle Subversion vara” CVS men bättre”, vilket bara understryker hur dominerande CVS hade blivit under 1990-talet.

CVS utvecklades först 1986 av en holländsk datavetare vid namn Dick Grune,som letade efter ett sätt att samarbeta med sina elever på ett kompilerprojekt.3 CVS var ursprungligen lite mer än en samling shell scriptswrapping RCS (Revision Control System), ett första generationens versionskontrollsystem som Grune ville förbättra. RCS fungerar enligt en pessimistisklåsningsmodell, vilket innebär att inga två programmerare kan arbeta på en enda fil atonce. För att redigera en fil måste du först be RCS om ett exklusivt låspå filen, som du behåller tills du är klar med redigeringen. Om någon annan ärredigerar redan en fil du behöver redigera, Du måste vänta. CVS förbättrades på RC och inledde andra generationens versionskontrollsystem genom att handla med pessimistisk låsmodell för en optimistisk. Programmerare kunde nu redigera samma fil samtidigt, slå samman sina ändringar och lösa eventuella konflikter. (Brian Berliner, en ingenjör som senare tog över CVS-projektet, skrev ett mycket läsbart papper om CVS innovationer 1990.)

i den meningen var CVS inte så annorlunda än Git, vilket också fungerarenligt en optimistisk modell. Men det är där likheterna slutar. Infact, när Linus Torvalds utvecklade Git, en av hans vägledande principer varwwcvsnd, eller ”vad skulle CVS inte göra.”När han var i tvivel om ett beslut strävade han efter att välja det alternativ som inte hade valts i utformningen avcv.4 så även om CVS föregår Git med över ett decennium, påverkade det Git asa slags negativ Mall.

Jag har verkligen tyckt om att leka med CVS. Jag tror att det inte finns något bättre sätt att förstå varför Gits distribuerade natur är en sådan förbättring av vad som kom förut. Så jag inbjuder dig att följa med mig på en spännande resa ochspendera de kommande tio minuterna av ditt liv att lära sig om en bit programvaraingen har använt under det senaste decenniet. (Se rättelse.)

komma igång med CVS

instruktioner för installation av CVS finns på projektets hemsida. På MacOS kan du installera CVS medhomebrew.

eftersom CVS är centraliserat skiljer det mellan klientsidan universum och serversidan universum på ett sätt som något som Git inte gör. Thedistinction är inte så uttalad att det finns olika körbara filer. Men för att börja använda CVS, även på din egen maskin, måste du ställa incvs-backend.

CVS-backend, centrallagret för all din kod, kallas förvaret.I Git skulle du vanligtvis ha ett arkiv för varje projekt, i Cvsförvaret innehåller alla dina projekt. Det finns ett centralt arkiv förallt, men det finns sätt att arbeta med bara ett projekt åt gången.

för att skapa ett lokalt arkiv kör du kommandotinit. Du skulle göra dettanågonstans global som din hemkatalog.

$ cvs -d ~/sandbox init

CVS låter dig skicka alternativ till antingen cvskommandot själv eller tillinit underkommandot. Alternativ som visas efter kommandot cvs är globala inatur, medan alternativ som visas efter underkommandot är specifika förunderkommandot. I detta fall är flaggan -d Global. Här händer det att berätta Cvsvar vi vill skapa vårt arkiv, men i allmänhet pekar flaggan -d på platsen för förvaret vi vill använda för en viss åtgärd. Det kan betedious att leverera -d flagga hela tiden, så CVSROOT miljövariabel kan ställas in istället.

eftersom vi arbetar lokalt har vi just passerat en sökväg för vårt -d argument,men vi kunde också ha inkluderat ett värdnamn.

kommandot skapar en katalog som heter sandbox I din hemkatalog. Om du listar innehållet i sandbox, hittar du att den innehåller en annan directorycalled CVSROOT. Denna katalog, inte att förväxla med miljönvariabel, innehåller administrativa filer för förvaret.

Grattis! Du har just skapat ditt första CVS-arkiv.

checkar in kod

låt oss säga att du har bestämt dig för att hålla en lista över dina favoritfärger. Du ären konstnärligt benägen men extremt glömsk person. Du skriver upp din listaf färger och spara den som en fil som heter favorites.txt:

blueorangegreendefinitely not yellow

låt oss också anta att du har sparat filen i en ny katalog som hetercolors. Nu vill du sätta din favoritfärglista under versionskontroll, för femtio år från och med nu blir det intressant att se tillbaka och se hurdin smak förändrats genom tiden.

för att göra det måste du importera din katalog som ett nytt CVSproject. Du kan göra det med kommandot import :

$ cvs -d ~/sandbox import -m "" colors colors initialN colors/favorites.txtNo conflicts created by this import

Här anger vi platsen för vårt förråd med -d flagagain. De återstående argumenten skickas till underkommandot import. Vi måste ge ett meddelande, men här behöver vi inte ett, så vi har lämnat detblank. Nästa argument, colors, anger namnet på vår nya katalog iförvaret; här har vi just använt samma namn som katalogen Vi är i.De två sista argumenten anger leverantörstaggen respektive släpptaggen.Vi pratar mer om taggar på en minut.

Du har just dragit ditt” färger ” – projekt i CVS-förvaret. Det finns ett par olika sätt att ta med kod i CVS, men det här är den metod som rekommenderas av Pragmatic Version Control UsingCVS, PragmaticProgrammer-boken om CVS. Vad som gör den här metoden lite besvärlig är att du måste kolla in ditt arbete färskt, även om du redan har anexisting colors katalog. Istället för att använda den katalogen kommer du attta bort den och kolla sedan in den version som CVS redan vet om:

$ cvs -d ~/sandbox co colorscvs checkout: Updating colorsU colors/favorites.txt

detta skapar en ny katalog, även kallad colors. I den här katalogen hittar du din ursprungliga favorites.txt – fil tillsammans med en katalog som heterCVS. KatalogenCVS är i grunden CVS motsvarande.git directoryi varje Git-arkiv.

göra ändringar

Gör dig redo för en resa.precis som Git har CVS ettstatus underkommando:

det är här saker börjar se främmande ut. CVS har inte begå objekt. I ovanstående finns det något som kallas en ”Commit Identifier”, men det här kan bara vara en relativt ny utgåva—inget omnämnande av en” Commit Identifier ” visas inpragmatisk versionskontroll med CVS, som publicerades 2003. (Lastupdate till CVS släpptes 2008.5)

medan du med Git skulle prata om versionen av en fil som är associerad med commit45de392, I CVS-filer versioneras separat. Den första versionen av yourfile är version 1.1, nästa version är 1.2, och så vidare. När grenar är inblandade läggs extra nummer till, så du kan sluta med något som 1.1.1.1 ovan, vilket verkar vara standard i vårt fall även om wehaven inte skapade några grenar.

Om du skulle köra cvs log (motsvarande git log) I ett projekt med lotsof-filer och åtaganden skulle du se en individuell historik för varje fil. Du har en fil i version 1.2 och en fil i version 1.14 i samma projekt.

Låt oss gå vidare och göra en ändring till version 1.1 av vårfavorites.txt fil:

 blue orange green+cyan definitely not yellow

När vi har gjort ändringen kan vi köra cvs diff för att se vad CVS tycker att vi har gjort:

CVS känner igen att vi lagt till en ny rad som innehåller färgen ”cyan” tillfilen. (Det står faktiskt att vi har gjort ändringar i” RCS ” – filen; du kan se attcvs aldrig helt släppte sin ursprungliga förening med RCS.) Skillnaden vi visas är skillnaden mellan kopian av favorites.txt I vår workingdirectory och 1.1.1.1-versionen lagrad i förvaret.

för att uppdatera versionen lagrad i förvaret måste vi begåändra. I Git skulle detta vara en process i flera steg. Vi måste ställa in förändringen så att den visas i vårt index. Då skulle vi begå förändringen. Slutligen, för att göra förändringen synlig för någon annan, måste vi driva åtagandet upp till ursprungsförvaret.

i CVS händer alla dessa saker när du kör cvs commit. CVS justbundles upp alla ändringar som den kan hitta och sätter dem i förvaret:

Jag är så van vid Git att detta slår mig som skrämmande. Utan en möjlighet att iscensätta förändringar, någon gammal sak som du har berört i din arbets directorymight hamna som en del av det offentliga förvaret. Har du passivt aggressivtrewrite en kollegas dåligt implementerade funktion av katartisk nödvändighet, aldrig tänkt för honom att veta? Synd, han tror nu att du är en kuk. Du kan inte heller redigera dina åtaganden innan du trycker på dem, eftersom ett åtagande är ett tryck. Tycker du om att spendera 40 minuter upprepade gånger med git rebase -i tills din localcommit-historia flyter som härledningen av ett matematiskt bevis? Tyvärr, du kan inte göra det här, och alla kommer att ta reda på att du inte faktiskt skriver dina tester först.

men jag förstår nu också varför så många tycker att Git är onödigt komplicerat.Om cvs commit är vad du var van vid, så är jag säker på att staging och pushingchanges skulle slå dig som en meningslös syssla.

När folk pratar om att Git är ett ”distribuerat” system, är detta främst skillnaden de menar. I CVS kan du inte göra åtaganden lokalt. Ett åtagande är eninlämnande av kod till centralförvaret, så det är inte något du kan görautan anslutning. Allt du har lokalt är din arbetskatalog. I Git har du ett fullfjädrat lokalt arkiv, så du kan göra åtaganden hela dagen längäven när du är frånkopplad. Och du kan redigera dessa åtaganden, återgå, filial, andcherry välja så mycket du vill, utan att någon annan behöver veta.

eftersom åtaganden var en större affär gjorde CVS-användare dem ofta sällan.Åtaganden skulle innehålla så många förändringar som idag vi kan förvänta oss att se i aten-commit pull request. Detta var särskilt sant om commits utlöste en CIbuild och en automatiserad testpaket.

om vi nu kör cvs status kan vi se att vi har en ny version av vår fil:

sammanslagning

som nämnts ovan kan du i CVS redigera en fil som någon annan redanredigera. Det var CVS: s stora förbättring på RCS. Vad händer när du behöverför dina ändringar tillbaka?låt oss säga att du har bjudit in några vänner att lägga till sina favoritfärger tilldin lista. Medan de lägger till sina färger bestämmer du dig för att du inte längresom färgen grön och ta bort den från listan.

När du går till begå dina ändringar, kanske du upptäcker att CVS meddelanden aproblem:

det ser ut som dina vänner begått sina ändringar först. Så din version avfavorites.txt är inte uppdaterad med versionen i förvaret. Om yourun cvs status ser du att din lokala kopia av favorites.txt är version1. 2 med vissa lokala ändringar, men lagringsversionen är 1.3:

Du kan köra cvs diff för att se exakt vad skillnaderna mellan 1.2 och1.3 är:

det verkar som att våra vänner verkligen gillar rosa. I alla fall har de redigerat enannorlunda del av filen än vi har, så ändringarna är lätta att slå samman. CVScan göra det för oss när vi kör cvs update, vilket liknar git pull:

$ cvs updatecvs update: Updating .RCS file: /Users/sinclairtarget/sandbox/colors/favorites.txt,vretrieving revision 1.2retrieving revision 1.3Merging differences between 1.2 and 1.3 into favorites.txtM favorites.txt

Om du nu tittar på favorites.txt, du kommer att upptäcka att det har ändrats för att inkludera de ändringar som dina vänner gjorde i filen. Yourchanges finns fortfarande där också. Nu är du fri att begå filen:

slutresultatet är vad du skulle få i Git genom att köra git pull --rebase. Yourchanges har lagts ovanpå dina vänners ändringar. Det finns ingen ” mergecommit.”

Ibland kan ändringar i samma fil vara inkompatibla. Om dina vänner hadchanged ” green ”till” olive”, till exempel, som skulle ha konflikt med yourchange ta bort” green ” helt och hållet. I början av CVS, detta var exaktden typ av fall som orsakade människor att oroa sig för att CVS inte var säker; RCS pessimistiska låsning säkerställde att ett sådant fall aldrig kunde uppstå. Men Cvsgaranterar säkerheten genom att se till att ingen förändring skrivs över automatiskt. Du måste berätta för CVS vilken förändring du vill fortsätta framåt, så när du kör cvs update markerar CVS filen med båda förändringarnapå samma sätt som Git gör när Git upptäcker en sammanslagningskonflikt. Du måste sedan redigera filen manuellt och välja den ändring du vill behålla.

det intressanta att notera här är att sammanslagningskonflikter måste åtgärdas innan du kan begå. Detta är en annan konsekvens av CVS centraliserade nature.In Git, du behöver inte oroa dig för att lösa sammanslagningar tills du trycker på de uppdrag du har lokalt.

taggar och grenar

eftersom CVS inte har lätt adresserbara begå objekt är det enda sättet att gruppera en samling ändringar att markera ett visst arbetskatalogtillstånd med ATAG.

skapa en tagg är enkelt:

$ cvs tag VERSION_1_0cvs tag: Tagging .T favorites.txt

Du kommer senare att kunna returnera filer till detta tillstånd genom att köra cvs update ochpassera taggen till -r flagga:

$ cvs update -r VERSION_1_0cvs update: Updating .U favorites.txt

eftersom du behöver en tagg för att spola tillbaka till ett tidigare arbetskatalogtillstånd uppmuntrar CVSencourages en hel del förebyggande taggning. Innan större refactors, till exempel, kan du skapa en BEFORE_REFACTOR_01 tagg som du senare kan använda om therefactor gick fel. Människor använde också taggar om de ville genereraprojektomfattande diffs. I grund och botten måste alla saker vi rutinmässigt gör idag med commithashes förväntas och planeras med CVS, eftersom du behövde ha taggarna tillgängliga redan.

grenar kan skapas i CVS, typ av. Grenar är bara en speciell typ avtag:

$ cvs rtag -b TRY_EXPERIMENTAL_THING colorscvs rtag: Tagging colors

som bara skapar filialen (i full vy av alla, förresten), så dufortfarande måste byta till den med cvs update:

$ cvs update -r TRY_EXPERIMENTAL_THING

ovanstående kommandon växlar till den nya filialen i din nuvarande workingdirectory, men pragmatisk versionskontroll med CVs rekommenderar faktiskt att du skapar en ny katalog för att hålla din nya filial. Förmodligen fann författarna attväxla kataloger lättare än att byta filialer i CVS.

pragmatisk versionskontroll med CVS rekommenderar också att du skapar branchesoff av en befintlig filial. De rekommenderar bara att skapa grenar avhuvudgren, som i Git kallas master. I allmänhet var förgreninganses vara en” avancerad ” CVS-färdighet. I Git kan du starta en ny filial förnästan någon trivial anledning, men i CVS-förgrening användes vanligtvis endast närverkligen nödvändigt, till exempel för utgåvor.

en gren kan senare slås samman till huvudlinjen medcvs update och-j flagga:

$ cvs update -j TRY_EXPERIMENTAL_THING

Tack för de begå historierna

under 2007 gav Linus Torvalds atalk om Git på Google. Git var väldigt nytt då, så samtalet var i grunden ett försök att övertyga ett rum fullt av skeptiska programmerare att de skulle använda Git, även om Git var så annorlunda än vad som helst då tillgängligt. Om du inte redan har sett samtalet, jagmycket uppmuntra dig att titta på det. Linus är en underhållande talare, även om hanever misslyckas med att vara hans brash själv. Han gör ett utmärkt jobb med att förklara varförDen distribuerade modellen för versionskontroll är bättre än den centraliserade. Många av hans kritik är reserverad för CVS i synnerhet.

Git är ett komplext verktyg. Att lära sig det kan vara enfrustrerande upplevelse. Men jag är också ständigt förvånad över de saker som Gitcan gör. I jämförelse är CVS enkelt och okomplicerat, men ofta omöjligt att göra många av de operationer vi nu tar för givet. Att gå tillbaka och använda CVSfor ett tag är ett utmärkt sätt att hitta dig själv med en ny uppskattning forgits kraft och flexibilitet. Det illustrerar väl varför förstå historienav mjukvaruutveckling kan vara så fördelaktigt-plocka upp och återgranskaföråldrade verktyg kommer att lära dig volymer om varför bakom de verktyg vi använderidag.

Om du gillade det här inlägget, mer som det kommer ut var fjärde vecka! Följ @TwoBitHistory på Twitter eller prenumerera på RSS-flödetför att se till att du vet när ett nytt inlägg är ute.

korrigering

Jag har fått höra att det finns många organisationer, särskilt risk-adverseorganisationer som gör saker som gör programvara för medicinsk utrustning, som fortfarande användscvs. Programmerare i dessa organisationer har utvecklat små knep förarbeta kring CVS begränsningar, till exempel att göra en ny filial för nästan everychange för att undvika att begå direkt till HEAD. (Tack till Michael Kohne förpointing detta ut.)

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *