Git (2005): Torvalds u bijesu piše alat za 10 dana
Jednom mu je Linux kernel zajednica ostala bez alata za suradnju preko noći, pa je Torvalds, umjesto da čeka spasitelja, u deset dana napisao Git — i to je, kao i uvijek kod njega, bila ta jeftinija opcija.
# da, poglavlje ima pjesmu. ne, nitko ne zna zašto.
Travanj 2005. Zamisli da cijela tvrtka — hajmo reći nekoliko tisuća ljudi razbacanih po cijelom svijetu — radi na najvažnijem komadu softvera na planetu, na jezgri operativnog sustava koji već pogoni pola interneta, i da sve to štima jedan alat koji im, u biti, netko samo posuđuje. Besplatno, ali s jednim tihim uvjetom: ne zabadaj nos u to kako radi ispod haube. Samo koristi, šuti i budi zahvalan.
To je BitKeeper — vlasnički sustav za upravljanje verzijama, dakle alat koji pamti svaku promjenu koda kroz vrijeme (zamisli beskonačni "Ctrl+Z" koji radi i za tisuću ljudi odjednom, ne samo za tebe), u vlasništvu firme BitMover i njezinog šefa Larryja McVoya. On je 2002. Linusu Torvaldsu dao nešto što se rijetko daje kernel zajednici zaraćenoj s pojmom vlasništva nad softverom — besplatnu licencu, uz stisak ruke i pogled koji govori: nemoj me zajebati.
Godinama je taj pakt nekako funkcionirao. Ne bez gunđanja, jasno — dio zajednice, onaj tvrdokorniji, Stallmanov ogranak (ljudi za koje kod mora biti otvoren i besplatan po principu, ne po hiru vlasnika), cijelo je vrijeme prigovarao da je apsurdno da najveći projekt otvorenog koda na svijetu ovisi o alatu koji sam otvoren nije. Ali Torvalds je pragmatičan tip. Radilo je. Zašto dirati?
Onda je netko dirnuo. Andrew Tridgell, poznat po tome što je reverse-engineerao Samb-u — dakle, otkrio kako nešto radi ispod haube bez pristupa izvornom kodu ili uputama, čistim strpljenjem i pokušajima — odlučio je proviriti u BitKeeperov protokol, onaj dogovoreni „jezik” kojim njegov server i klijentski programi razmjenjuju podatke. Ne da ga kopira, samo da napravi otvoreni klijent koji zna tim jezikom progovoriti. Legenda kaže da je sav postupak sveo na to da se telnetao na server i utipkao help. Zvuči kao šala. Nije bila.
I tako je, negdje sredinom travnja 2005., nekoliko tisuća programera najvećeg zajedničkog softverskog projekta na svijetu preko noći ostalo bez alata kojim su ga godinama sklapali. Bez prijelaznog roka, bez plana B, bez ičega — samo prazan prostor gdje je jučer bio radni proces.
Torvalds je, po svemu sudeći, bio bijesan. A ti već znaš što se dogodi kad je Torvalds bijesan i nezadovoljan postojećim alatima — vidjeli smo to jednom, 1991., kad je iz čistog nezadovoljstva jednim operativnim sustavom napisao drugi, vlastiti. Sad je isti čovjek, četrnaest godina stariji, gledao u prazan direktorij gdje bi trebao stajati sustav za verzioniranje, i pomislio ono što uvijek pomisli kad mu se ne sviđa kako svijet radi stvari.
Napravit ću bolje. Sam. I brzo.
Postavimo scenu. Linux kernel — da, onaj isti koji smo u prošloj knjizi ostavili kao hobi-projekt finskog studenta koji se žalio da mu ništa drugo ne radi — do 2002. je narastao u nešto što više nitko ne kontrolira ručno. Tisuće developera, desetci tisuća promjena, i jedan Linus Torvalds koji do tada sve zakrpe prima — ozbiljno — preko e-maila i tarballa (zamisli to kao spakiranu kutiju sa svim fajlovima, poslanu kao privitak) koje ručno raspakira i spaja. To nije radni proces. To je čudo da ništa nije izgorjelo do temelja.
I tu upada McVoyev BitKeeper. Poštenja radi, on je kernel zajednici ponudio besplatnu licencu. Ne open source, ne slobodno, nego besplatno za korištenje, dok god ne diraš unutrašnjost i ne praviš konkurentski proizvod na temelju reverse engineeringa. Nagodba stara kao sam posao: uzmi alat, ne zanovijetaj.
Torvalds je pragmatičar do srži — sjećaš se, isti onaj koji je desetljeće ranije licencirao kernel pod GPL-om, ali je pri odabiru radnih alata uvijek gledao što stvarno radi, ne što je ideološki čisto. BitKeeper je radio. Rješavao je baš onaj problem koji je Torvaldsa najviše mučio — distribuiranu suradnju bez jednog gušećeg centra — i to je bilo dovoljno.
Sustav je funkcionirao — sve dok jednog dana 2005. nije naletio na Tridgella, koji je htio napraviti otvoreni klijent koji razgovara s BitKeeper serverima — ne kopirati kod, samo protokol, onaj dogovoreni „jezik” kojim se dva računala razumiju.
I tu dolazi obrat koji čini ovu priču onim što jest — ne priča o hakiranju, nego priča o kolektivnoj kazni. McVoy nije tužio Tridgella. Umjesto toga, povukao je besplatnu licencu za cijelu kernel zajednicu. Odjednom, tisuće developera koji nikad nisu ni čuli za Sambin protokol, koji su samo htjeli poslati zakrpu za petak popodne, ostali su bez alata kojim su godinama radili. Kazna nije stigla krivcu. Stigla je svima.
Torvalds se našao pred izborom koji je iz dna duše mrzio: vratiti se ručnom slanju tarballova kao 2002., prihvatiti neki drugi vlasnički alat i za par godina odglumiti istu dramu iznova, ili — pa, vidjet ćemo u sljedećoj sekciji što je odlučio, ali ako znaš i mrvicu o čovjeku, već pretpostavljaš da rješenje neće biti ni jedno od ta dva.

Deset dana (opet)
Torvalds nije sjeo pisati alat za kontrolu verzija. Sjeo je pisati alat koji rješava JEDAN problem — njegov problem — jer se u tom trenutku svi ostali problemi nisu doimali njegovima. Tisuće developera bez alata, kernel koji se ne smije zaglaviti, i muškarac koji je, sjetimo se, cijeli Linux napisao jer mu se nije svidjelo ono što je bilo dostupno (K4, pogl. 7 — isti čovjek, ista alergija na tuđe kompromise). Razlika je što ovaj put nije imao dvadeset i jednu godinu i hobi-projekt na koledžu. Imao je nekoliko milijuna linija kernel koda, globalnu zajednicu koja je čekala, i otprilike nulu strpljenja.
Zato je bio brutalno jasan što alat MORA raditi, a to je rijedak luksuz kad pišeš softver — obično pogađaš zahtjeve, ovdje ih je znao napamet, jer ih je upravo živio kao žrtva. Distribuirano, jer je centralni server (BitKeeperov, ili bilo čiji) bio upravo ona stvar koja je cijelu priču srušila u jednom potezu — jedna licenca, jedan čovjek, i cijela zajednica stoji. Brzo, jer je kernel patch nekad znao imati desetke tisuća linija promjena i Torvalds nije imao namjeru čekati minutu da mu alat kaže je li nešto radio. I integritet — svaka promjena mora nositi dokaz da je upravo ta promjena, ne neka slična, ne neka tiho prepravljena. To zadnje nije bio hir. Bio je direktan odgovor na osjećaj koji ga je progonio otkad je McVoy povukao BitKeeper: da povijest projekta može ovisiti o dobroj volji jednog vlasnika softvera. Nikad više.
I to se vidi. Vidi se u tome što je Git, unatoč kriptičnim naredbama i sučelju koje izgleda kao da ga je crtao netko tko mrzi korisnike (o tome više malo kasnije), arhitektonski čvrst od prvog dana — koncepti se od 2005. nisu promijenili, samo su omotani u ljepše alate. Za usporedbu: JavaScript je, sasvim slučajno, isto nastao za desetak dana (Brendan Eich ga je sklepao 1995. u sličnom vremenskom stisku), i desetljećima je čistio posljedice tih dana — recimo, poznatu grešku po kojoj naredba „typeof null” vraća „object”, iako null očito nije objekt. Git nije morao čistiti gotovo ništa. Kad znaš točno što gradiš, brzina ne znači nemar — znači da ti je jasnoća već u glavi, pisanje je samo prenošenje.
Svega nekoliko dana kasnije Git je znao klonirati sam sebe — repozitorij je mogao kopirati vlastiti kod i vlastitu povijest, baš kao što će uskoro to raditi za tuđe projekte. Torvalds je time namjerno dokazao poantu — alat za praćenje kernela sad je pratio i vlastiti razvoj, u istom repozitoriju, bez ičega posuđenog od BitKeepera. Zajednica koja je tjedan dana ranije stajala bez alata odjednom je imala nešto brže od svega što je prije koristila. Sad je trebalo samo — i ovo je onaj dio priče gdje se svi iznenade — da to isto shvate i van kernela.

Ideja koja sve mijenja: distribuirano
OK, sad dolazimo do dijela zbog kojeg je ovo poglavlje, a ne samo bilješka o jednom bijesnom vikendu. Torvalds nije samo napisao brži BitKeeper. Napravio je nešto filozofski drugačije, i baš ta razlika je Git na kraju odvela od hakerskog alata do infrastrukture cijele industrije.
Zamisli da radiš u firmi gdje postoji jedna, jedina, prava verzija dokumenta — leži na serveru u podrumu, i svaki put kad želiš nešto promijeniti, moraš se spojiti na taj server, uzeti dokument, izmijeniti ga, vratiti ga. Ako server padne, nitko ne radi. Ako si na vlaku bez interneta, ne radiš. Tako su radili skoro svi alati za verzioniranje prije Gita — CVS, Subversion, svi po istom principu: postoji centar, a ti si samo posjetitelj koji svraća po dozvolu.
Git je rekao: ne. Kad kloniraš git repozitorij (kloniranje je jednostavno preuzimanje kompletne kopije na svoje računalo), ne uzimaš trenutnu snimku stanja koda — uzimaš cijelu povijest. Svaki commit koji je ikad napravljen, svaka grana, svaka poruka uz commit, sve. A commit je, da razjasnimo odmah, zapisana promjena koda — snimka stanja u jednom trenutku, popraćena porukom u kojoj (idealno) piše zašto je ta promjena napravljena. Tvoj lokalni klon dakle nije siromašna kopija nečeg „pravog” što stoji na serveru — on je jednako pravi kao i original. Možeš isključiti internet, otići u planine na tjedan dana, i dalje raditi commitove, gledati povijest, mijenjati kod, sve normalno — jer ti za ništa od toga ne treba centar. Centar postoji samo onda kad se dvoje ljudi žele dogovoriti tko je što promijenio. Do tada je svaki laptop na svijetu koji ima klon repozitorija — punopravna kopija istine.
Druga stvar, koja izlazi direktno iz prve: grane su u Gitu skoro besplatne. U starim sustavima grananje koda bio je ozbiljan poduhvat — kopiraš cijeli direktorij, čekaš, moliš se da se sve spoji natrag bez katastrofe. U Gitu je grana samo pokazivač, jedan mali zapis koji kaže „ovdje je vrh ove linije razvoja”. Stvaranje nove grane traje koliko traje da otipkaš naredbu. Posljedica: developeri su počeli eksperimentirati bez straha. Želiš probati ludu ideju? Napravi granu, probaj, ako ne valja — obriši, nitko neće ni znati da je postojala. To je jedna od onih promjena koje ne zvuče revolucionarno dok se ne sjetiš koliko je straha nekad postojalo oko te jedne riječi — „branch”, grana.
Treća stvar je ta koja je Gitu dala integritet kojeg ni Torvalds nije bio spreman kompromitirati — content-addressing, odnosno adresiranje po sadržaju. Svaki objekt u Gitu, svaki commit, svaki file, svaka verzija bilo čega, dobiva svoj identifikator izračunat iz vlastitog sadržaja, kroz takozvanu SHA hash funkciju — matematički postupak koji od bilo kojeg sadržaja, koliko god velikog, generira jedinstveni niz znakova, nešto kao otisak prsta tog sadržaja. Promijeniš i jedan zarez u fileu koji je commitovan prije tri godine, i taj otisak prsta postane potpuno drugačiji — cijela povijest iza njega, sva stabla koja su na njega upućivala, sve se promijeni. Ne možeš tiho zamijeniti jednu verziju drugom i nadati se da nitko neće primijetiti. Povijest u Gitu nije zapis koji vjeruješ jer ti neko autoritativno tijelo kaže da je istinit — povijest u Gitu je matematički dokaziva. Ili se otisci prstiju, hashevi, slažu, ili je nešto krivotvoreno.
Zvuči kao paranoidna značajka. I jest. Ali sjeti se odakle Torvalds dolazi — cijela drama s BitKeeperom počela je zato što je jedan čovjek, McVoy, imao potpunu kontrolu i mogao je povući tepih ispod nogu tisućama ljudi jer je bio jedini autoritet. Sjeti se i zašto Linux kernel postoji uopće — Torvalds desetljećima upravlja projektom u koji stotine ljudi šalju patcheve, odnosno gotove pakete izmjena koda koje predlažu da se ubace u projekt, a on nikad, ni u jednom trenutku, nije morao nekome doslovno vjerovati na riječ da je kod koji šalje isti kod koji je poslao prije pet minuta. Nepovjerenje kod njega nije osobna mana. Nepovjerenje je arhitektonski princip.
I to je ono što Git zapravo jest, ispod cijele priče o brzini i granama: Linuxov filozofski model pretvoren u alat. Nema centralnog autoriteta kojem moraš vjerovati — postoji distribuirana mreža jednako vrijednih kopija. Nema riječi „vjeruj mi” — postoji hash koji se ili poklapa ili ne poklapa. Isti čovjek koji je izgradio operacijski sustav na principu da nijedna tvrtka ne smije imati ključeve od svega, izgradio je i alat na principu da nijedan server ne smije imati monopol na istinu. Ironično dosljedno, kad malo bolje pogledaš.
Sad, ima jedna sitna napukotina u toj priči o savršenoj decentralizaciji, i doći ćemo do nje sasvim brzo — ali za sada, zapamti samo ovo: Git je riješio problem povjerenja bez povjerenja. Matematikom, ne autoritetom. To je razlog zašto je alat napisan za desetak dana danas, dvadesetak godina kasnije, tiho ispod svega što danas zoveš „softverskom industrijom”.

Od hakerskog noža do standarda
Torvalds je za deset dana napisao alat koji funkcionira, ne alat koji je ugodan. To su dvije različite stvari, i Git je do dana današnjeg živi dokaz te razlike. Prva odluka koja je oblikovala sve poslije: Git je zapravo dva alata u jednom. Ispod je »plumbing« (vodovod) — sirove, niskorazinske komande koje čačkaju direktno po objektima, hashevima, stablima. Iznad toga je »porcelain« (keramika) — sučelje koje bi normalan čovjek trebao koristiti: commit, push, pull, branch. Vodovod i keramika, baš tako se to i zove u dokumentaciji, i nije to slučajna metafora nego prilično točna slika: negdje duboko u zidu cijevi rade svoj posao, a ti dodiruješ samo glazirani dio koji izgleda pristojno.
Problem je što je taj glazirani dio dizajnirao čovjek koji je zapravo htio da svi koriste vodovod. Torvalds nije pisao Git za developere koji će za petnaest godina klikati dugme „commit” u VS Code-u. Pisao ga je za kernel hakere koji su navikli na to da alat radi točno ono što kažeš i ništa više, i kojima je naredba „git checkout -- .” potpuno razuman način da izraziš „odbaci sve moje promjene”. Za njih je to bilo logično. Za ostatak planete koji je došao poslije, Git je dugo izgledao kao sef s kombinacijom napisanom na klinski nerazumljivom jeziku.
Ali dizajn za hakere, iako bolan za sve ostale, imao je jednu prednost koju ništa drugo na tržištu u tom trenutku nije nudilo — bio je nevjerojatno moćan ispod haube. Subversion je bio jednostavan zato što je bio centraliziran i ograničen: sve što si mogao učiniti, radio si prema jednom serveru koji je uvijek imao zadnju riječ. Mercurial je, kao i Git, bio distribuiran, ali čišćeg i pitomijeg sučelja, s manje ćoškova o koje se možeš ozlijediti. Objektivno gledano, za normalnog developera Mercurial je 2008. godine bio bolji alat. Objektivno gledano, izgubio je.
Zašto? Ne zato što je Git bio tehnički superiorniji za svakodnevnu upotrebu — bio je gori za nju. Pobijedio je zato što je bio Torvaldsov, zato što ga je kernel, najveći i najprestižniji open source projekt na planeti, odmah počeo koristiti, i zato što se oko njega, sporo, nakupljao kritičan broj ljudi kojima je vrijedilo naučiti kriptičan jezik jer su svi ostali oko njih taj jezik već govorili. Mrežni efekt je čekao samo jednu stvar da ga upali — nešto što će uzeti taj hakerski nož i staviti mu ugodnu dršku, dodati gumbiće, slike i socijalnu mrežu oko koda. To dolazi u sljedećem poglavlju, zove se GitHub, i bez njega bi Git vjerojatno danas bio omiljena igračka desetak tisuća ljudi koji vole terminal, a ne alat kojim cijela planeta piše softver.
Standard ne postaje standard zato što je najljepši. Postaje standard zato što je prvi bio tu, dovoljno dobar i dovoljno tvrdoglav da ne popusti pred vlastitom nezgrapnošću dok mu netko drugi ne posudi lice.

Ostavština: povijest kao struktura podataka
Kad danas otvoriš git log na bilo kojem projektu, gledaš nešto što nijedan alat prije Gita nije baš uspio uhvatiti: povijest odlučivanja, ne samo povijest teksta. Commit nije samo snimka stanja fajlova u nekom trenutku — commit je jedinica misli. Netko je, u nekom trenutku, s nekim razlogom (nadamo se opisanim u poruci, a ne samo »fix«), rekao: ovo je sad novo stanje istine. Cijela arhitektura Gita građena je oko te rečenice. Svaki commit pokazuje na svog roditelja, roditelj na svoga, sve do prvog, i tako dobiješ lanac odluka koji možeš pratiti unatrag, kao da čitaš dnevnik nekoga koji je, u pravilu, bio pod stresom i kasnio s rokom.
I onda dođu alati koji tu strukturu iskorištavaju za stvari koje Torvalds možda nije ni planirao u onih deset dana, ali su prirodna posljedica dobrog modela. git blame ti kaže tko je i kada napisao svaku pojedinu liniju koda koja te sada muči — arheologija u pravom smislu, samo umjesto slojeva zemlje kopaš slojeve commitova. git bisect je još luđi: umjesto da ručno prolaziš kroz tisuće commitova tražeći onaj koji je unio bug, prepustiš alatu da radi ono što bismo mi radili kad tražimo broj između 1 i 1000 — ne pitaš redom je li 1, je li 2, je li 3, nego uvijek pogađaš sredinu i dijeliš problem na pola, dok ne ostane samo jedan mogući krivac. Ne moraš pogađati, ne moraš se sjećati — repozitorij se sjeća za tebe, savršeno i bez emocija, čega ljudsko sjećanje nikad nije bilo kadro.
Iz toga se izlegla cijela kultura: verzioniraj sve. Ne samo kod — konfiguraciju infrastrukture, dokumentaciju, pa i zakone (ozbiljno, postoje parlamenti i gradske uprave koje nacrte zakona vode kroz Git, s pull requestovima na amandmane — pull request je, pojednostavljeno, prijedlog promjene koji netko šalje na pregled prije nego što uđe u glavni, važeći tekst, baš kao amandman koji prvo mora prođe odbor prije nego postane dio zakona). Kad imaš alat koji besplatno i pouzdano čuva svaku promjenu i svaki razlog promjene, prirodno pitanje postane: zašto to ne radimo za baš sve što nam je važno? Odgovor je — sad radimo. Git je prestao biti alat za programere i postao model za pamćenje odluka, pun stop.
A onda, na kraju svega, jedna sitna, tiha ironija koju vrijedi ostaviti da visi u zraku umjesto da je ugasimo pametnom rečenicom: Git je, u svojoj srži, dizajniran da bude decentraliziran do bola — svaki klon je punopravna kopija cijele povijesti, nema glavnog servera koji je »taj pravi«. Torvalds je to htio baš zato da nitko, nikad više, ne može jednom odlukom oduzeti zajednici njezinu povijest, kao što je BitKeeper oduzeo. I uspio je. Model je čist, filozofski dosljedan, gotovo anarhističan.
A onda su svi, praktički svi, taj savršeno decentralizirani alat počeli koristiti kroz jedan, jedini, centralizirani web servis. Ali o tome — u sljedećem poglavlju.