RAZUMETI GIT: Praveći ga od nule

Share

Ovaj članak podrazumeva osnovno razumevanje Git-a, ako ste se ikad pitali kako Git radi, i još važnije, zašto je sve tako komplikovano.

Da bi bolje razumeli Git, možemo zamisliti sledeći misaoni eksperiment. Pretpostavimo da su Alisa, Bob i Čarli tri posvećena i vredna developera, ali da se jednog posebno baksuznog dana njihov Centralizovani Verzioni Sistem (CVS) pokvario. Sada, pošto su svo troje izuzetno uporni, oni nastavljaju sa radom i dostavljaju svoje izmene klijentu. Na kraju dana, kada svo troje imaju veliki broj izmena, njima treba neki način da spoje svoje izmene.

Da im CVS radi, oni bi svakoj izmeni dali sekvencijalni broj. Ali, pošto je svako od njih radio nezavisno, treba im zajednički, nezavisan način da pronađu fajlove i izmene koje su načinili, a koji funkcioniše bez obzira ko je radio na fajlu i kad. Alisa predlaže da se koristi heš funkcija koja uzima sadržaj fajla. S obzirom da heš funkcija zavisi samo od sadržaja fajla, možemo lako razlikovati fajlove na osnovu njihovog SHA1 broja, bez obzira ko je napravio izmenu i kada. Kao bonus, ako su dva developera napravili iste izmene, ti fajlovi će imati isti SHA1.

U Linux konzoli ako izvršimo:

$ echo 'test content' | git hash-object -w --stdin

i uporedimo sa:

$ echo 'test content' > test.txt
$ git hash-object -w test.txt

treba da dobijemo istu heš vrednost:

d670460b4b4aece5915caf5c68d12f560a9fe3e4

Za Git, heš test.txt i naša echo komanda su identične. U Git-u se takvi elementi nazivaju blob-ovi.
Ok, to je super za poređenje fajlova, ali Bob je primetio da u svakom većem projektu ima veći broj izmena. Da bi ovo rešili Alisa predlaže da se prate svi fajlovi u nekoj vrsti liste, koja može da podrži hijerarhiju direktorijuma. Čarli primećuje da bi ovo bilo najbolje rešeno nekom vrstom kompozitnog obrasca. Alisa primećuje da će listovi kompozitnog obrasca biti blob-vi, dok se kompozitni elementi prirodno mapiraju na foldere.

Bob se seća da po Unix filozofiji („Sve je fajl“) direkotrijumi su u stvari fajlovi koji u sebi imaju liste fajlova ili drugih direktorijuma. Čarli primećuje da Unix koristi inode kao identifikatore, ali da bi oni bili neupotrebljivi u njihovom sistemu. Bob primećuje da oni već imaju jedinstvene identifikatore – heš vrednosti.

Zato oni definišu njihovu kompozitnu strukturu ovako:

blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 README.md
tree 9c7e41c855b3b3a976a72dd268db17a379c0ab0e lib
blob d670460b4b4aece5915caf5c68d12f560a9fe3e4 test.txt

što nije previše drugačije od izlaza git cat-file ispod:

$ git write-tree
0406b210c2c38cd63eddbad2ea261251e039fbe4
$ git cat-file -p 0406
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 README.md
040000 tree 9c7e41c855b3b3a976a72dd268db17a379c0ab0e lib
100644 blob d670460b4b4aece5915caf5c68d12f560a9fe3e4 test.txt

U primeru iznad, lib je direktorijum koji sadrži jedan Ruby fajl, koji možemo videti u listi, kao i njegov sadržaj:

$ git cat-file -p 9c7e4
100644 blob 5635b63d64f0bf8cba141d49918e8f21b9940aed HelloWorld.rb

Ili vizualizovano:

Za sada, imamo način da jedinstveno prepoznajemo fajlove i način da uhvatimo stanje fajl sistema u jednom momentu. Ovo je začetak sistema kontrole verzija. Sada, Alisi, Bobu i Čarliju treba način da snime svoje izmene i dodaju neke meta-podatke.

Alisa predlaže da dodamo text i vezu ka drvetu kako bi imali nešto što podseća na izmenu u CVS-u. Bobova sugestija je i da se dodaju neki lični podaci i datum izmene. Tako da izmena postaje:

Tree: 0460b…
Author: Alice@example.org
Time: Tue May 02 2018 12:00:12 +0100
First commit

Ili vizuelni:

Čarli dodaje da ako dodamo još jednu izmenu, treba nam i način da referenicramo prethodni komit, kako bi znali koji komit prati koji. Ovo malo komplikuje našu izmenu (na primer):

Tree: ae996
Parent: 5ba2b (First commit)
Author: Alice@example.org
Time: Tue May 02 2018 12:00:12 +0100
Second commit

Bob primećuje da, pošto je samo README.md promenjen, naš drugi komit može da pokazuje na stare fajlove. U praksi ovo omogućuje Git-u da uštedi prostor, jer će bilo koja dva identična fajla imati isti heš i biti skladišteni samo jednom. Dakle naš drugi komit izgleda ovako:

Sa ovim, naš osnovni oblik verzionog sistema Alisa, Bob i Čarli uspevaju da reše svoje probleme. Na njihovu sreću nije bilo potrebe da se spajaju izmene.
Za više detalja o Gitu pročitajte na Git Internals zvaničnom sajtu, kao i na sajtu Git from bottom up.

Share

Prijavi se da prvi dobijaš nove blogove i vesti.

Ostavite odgovor

Daniel Fat

Java Developer @ Intens
mm

Daniel Fat je Java Developer i Git entuzijasta. Zavrsio je Fakultet tehničkih nauka u Novom Sadu 2010, sa Master diplomom. U slobodno vreme radi na open source projektima.

Prijavi se da prvi dobijaš nove blogove i vesti.

Kategorije