Ko se boji Git-a još

Git logoGit je sistem za praćenje i kontrolu revizija fajlova. Cilj ovog članka je da korisnika uputi u osnove ovog alata, da pokaže koliko je jednostavan kao i da ga motiviše da počne da ga koristi. Ja već nekoliko godina koristim SVN ali me rastuća popularnost Git-a podstiče da ga što bolje proučim i primenim. Nije mi ovo prvi put da se susrećem sa Git-om. Koristio sam ga po sistemu problem/rešenje tj. naučio sam osnovne stvari ali kada je dolazilo do problema bilo kakve vrste pribegavao sam najgorim mogućim rešenjima. Nadam se da će mnogi koji su ovaj alat koristili na sličan način naći u ovom postu izvor motivacije da svoje znanje iz ove oblasti podignu na viši nivo. Siguran sam da će im u predstojećem periodu zatrebati. Danas se gotovo svi open source projekti oslanjaju na ovaj alat a podatak da ga u 2011. godini koristilo 11% a u 2012. godini čak 27% developera jasan je pokazatelj njegove vrednosti.

Kako je sve počelo

Nastao je iz praktične potrebe zajednice koja je bila okupljena oko razvoja kernela Linux-a. Najpre je u ovu svrhu korišćen softver BeetKeeper. Vremenom je došlo do pogoršanja odnosa između Linux zajednice i firme koja je stajala iza Bitkeeper-a te je Linus Torvalds, nezadovoljan ostalim alatima koji su tada bili dostupni, odlučio da napravi novi sistem za verzionisanje gde će primeniti dobru praksu i iskustva koja su stekli koristeći BeetKeeper. Sam naziv potiče od engleske reči “git” što u prevodu znači glup, neprijatan čovek. Linus u šali kaže “I’m an egotistical bastard, and I name all my projects after myself. First Linux, now git”. Ciljevi koje su postavljeni pred novi sistem su:

  • Da bude brz
  • Da bude jednostavnog dizajna i jednostavan za učenje
  • Da podržava veliki broj branch-eva
  • Da bude potpuno distribuiran
  • Da bude siguran i otporan na greške
  • Da bude sposoban da podrži velike projekte

Možemo slobodno reći da je ovaj alat ispunio zacrtano u svim kategorijama.

Tipovi sistema za kontrolu verzija

Sistemi za kontrolu verzija predstavljaju alate koji služe kao podrška timovima i pojedincima u praćenju razvoja i održavanju projekata. Koristeći ove sisteme svi podaci su sigurniji, bolja je sinhronizacija između članova tima, smanjuje se mogućnost greške i poboljšava se sam proces vođenja projekta. Postoje dve vrste sistema za kontrolu verzija – centralizovani (CVCS) i distribuirani (DVCS). Prvoj vrsti pripadaju alati kao što su SVN, Perforce i CVS dok u drugu vrstu spadaju Mercurial, Bazaar, Darcs i Git. Kod CVCS svi podaci o verzijama se nalaze na centralizovanom serveru dok klijenti imaju dostupnu samo trenutnu verziju na kojoj rade. Ovo je svakako lakše za održavanje i administriranje ali u slučaju otkaza ovog sistema gube se sve informacije o projektu. Kod DVCS klijenti pored poslednje verzije preuzimaju i kompletnu bazu o svim verzijama na tom repozitorijumu. U slučaju bilo kakvog otkaza sistema dovoljno je da jedan od klijenata postavi podatke na server i svi problemi su vrlo brzo rešeni.

Kako Git funkcioniše

Pre nego što pređemo na konkretne primere potrebno je objasniti kako određeni delovi funkcionišu a sve u cilju bržeg učenja. Ono što predlažu svi priručnici jeste da zaboravimo sve što smo do sada znali o bilo kom drugom sistemu za verzionisanje. Kod Git-a kao predstavnika DVCS prilikom kloniranja nekog repozitorijuma kopira se celokupna baza o projektu a ne samo poslednja verzija. To znači da su nam lokalno raspoložive sve verzije fajlova – od prve do poslednje. Budući da se svi podaci nalaze u lokalu odziv je neuporedivo brži kada su nam potrebne informacije o repozitorijumu i fajlovima u njemu. Generalno govoreći većina operacija se odvija lokalno bez potrebe za komunikacijom sa serverom. Git ima potpuno različit princip čuvanja podataka od svih ostalih sistema. Svaki put kada mu se podaci proslede na čuvanje sačuva se celokupno stanje sistema, snima se tzv. snapshot svakog fajla. Ukoliko neki fajl nije promenjen onda se čuva pokazivač na njegovo prethodno stanje. Ovo u praksi znači da možemo čitav sistem da preuzmemo u određenoj verziji. Ostali sistemi čuvaju informacije o osnovnom, prvom prosleđenom fajlu, a zatim vode računa o promenama koje su se na njemu desile. Za očekivati je da je prostor koji zauzima projekat koji je na Git-u mnogo veći od istog tog projekta na SVN-u ali to nije slučaj – naprotiv – mnogo je manji.

Tri glavna elementa Git-a su:

  1. Repozitorijum (Git repository, Repository ili kratko Repo). Ovde se nalaze svi metapodaci i baza podataka o našem projektu. Kada neko preuzima (klonira) projekat kopira mu se ovaj direktorijum.
  2. Radni direktorijum (Working directory). Predstavlja lokalni folder u kome menjamo i kreiramo fajlove koji su obuhvaćeni verzionisanjem
  3. Prostor pripreme (Staging area). Svi fajlovi pre nego što se komituju moraju da budu pripremljeni za to. Mesto gde se oni smeštaju jeste ovaj pripremni deo. Samo oni fajlovi koji se nalaze ovde biće komitovani. Budući da Git pravi snapshot svih fajlova prilikom komita sasvim je logično postojanje pripremnog dela jer ćemo najpre ovde smeštati fajlove i na taj način sistem neće morati da pravi snapshot kad god imamo spreman neki fajl.

Fajlovi u Git repozitorijumu mogu imati statuse:

  • Praćeni (Tracked) – Imaju ga svi fajlovi koji su pod kontrolom Git-a. Oni mogu biti izemenjeni, neizmenjeni, i pripremnljeni (modified, unmodified i staged).
  • Nepraćeni (Untracked) – u okviru repozitorijuma mogu biti fajlovi koji nisu pod kontrolom i nad njima Git nema nikakvog uticaja. Sve nove fajlove koje kreiramo unutar ili prekopiramo u repozitorijum imaju u startu ovaj status. Ove fajlove samo jedna komanda deli od toga da postanu praćeni. Imamo i mogućnost da konfiguracijom podesimo određene tipove fajlova koje će sam Git po automatizmu da ignoriše

Instalacija

Git server se može instalirati na Linux-u, Windows-u i MacOS-u. U ovom postu ću pokazati instalaciju na Ubuntu a uputstva za instalaciju na ostalim sistemima možete lako pronaći. Od verzije 12.04 Ubuntu za instalaciju Git-a ima paket koji se zove git. Za ranije verzije ovaj paket se zove git-core. Ovo je osnovni paket. Ostale pakete možemo podeliti:

  • transfer sa drugih sistema za kontrolu verzija – git-arch, git-cvs, git-svn
  • grafički UI – git-gui, gitk, gitweb
  • email – git-email
  • za deljenje repozitorijuma – git-daemon-run

Komanda sa osnovnu instalaciju bila bi:

sudo apt-get install git git-doc gitweb git-gui gitk git-email git-svn git-daemon-run

 

Sve je spremno da postavimo neki projekat pod Git kontrolu. Proces ćemo objasniti preko osnovnih elemenata Git-a.

Repozitorijum

Otvorićemo novi folder i nazvati ga gitrepo. Da bi od njega napravilli repozitorijum dovoljno je da se pozicioniramo unutar tog foldera i unesemo sledeću komandu:

git init

Sistem će nam poslati sledeći odgovor:

Initialized empty Git repository in /var/git/gitrepo/.git/

To znači da smo uspešno kreirali naš prvi git repozitorijum. Unutar našeg foldera kreiran je novi podfolder .git i u njemu će se nalaziti celokupna baza o našem projektu. Kako bismo videli trenutni status direktorijuma ukucaćem komandu:

git status

Budući da u ovom trenutku ništa nije menjano u repozitorijumu odgovor sistema je:

# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)

Kao što vidite već smo dobili uputstvo šta treba dalje da radimo. Budući da smo kreirali novi repozitorujum mi nemamo fajlova koje bi u startu dodali u repozitorijum. Preći ćemo na sledeći korak.

Radni direktorijum

Sada kada imamo formiran repozitorijum pokazaćemo kako se on klonira. Želimo da radimo sa našim, radnim direktorijumom i da tu pripremamo izmene koje bi zatim komitovali u repozitorijum. Kloniraćemo naš lokalni, upravo formirani repozitorijum. Budući da se on nalazi u lokalu kao putanju mogu uneti putanju do lokalnog foldera prilikom kloniranja. Pozicioniraćemo se na folder u kome želimo da smestimo naš radni direktorijum. U mom slučaju komanda za kloniranje je sledeća:

git clone /var/git/gitrepo

Hajde da kreiramo novi fajl fajl first.txt u našem radnom direktorijumu i unesite proizvoljni sadržaj u njega. Kada nakon toga zatražimo status dobijamo sledeći odgovor:

# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	first.txt
nothing added to commit but untracked files present (use "git add" to track)

Trenutno u direktorijumu imamo jedan fajl koji ima status nepraćen (Untracked). Sistem nam je pružio informaciju šta dalje treba da uradimo. Potrebno je da ovaj fajl prvo smestimo u pripremni prostor.

Pripremni prostor

Ovo je deo koji je potpuno zbunjujući za sve one koji su koristili SVN. Pre nego se nešto komituje mora da se smesti u pripremni prostor. Samo fajlovi koji se nalaze u ovom prostoru mogu se komitovati. Kao što smo rekli svaki komit znači i snapshot celog sistema te je postojanje pripremnog dela sasvim opravdano. Hajde da dodamo fajl first.txt u pripremni prostor. Sistem nas je uputio da koristimo komandu git add da bismo ovaj fajl označili za praćenje. Ovoj komandi možemo reći da ubaci samo ovaj fajl – git add first.txt, sve fajlove git add . ili samo npr. fajlove sa ekstenzijom txt – git add *.txt. Sada smo prebacili fajl u pripremni prostor. Status direktorijuma sada je:

# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached ..." to unstage)
#
#	new file:   first.txt
#

Fajl first.txt je spreman da se komituje u repozitorijum.

Komitovanje

Pre prvog komitovanja potrebno je podesiti osnovne infomarcije o nama kao korisnicima. Ovi podaci pojaviće se u prikazu istorije promena na fajlovima. Potrebno je uneti odgovarajuće podatke u sledećim komandama:

git config --global user.name "Ime Prezime"
git config --global user.email example@email.com

Pre svakog komita potrebno je, a mogu slobodno reći i obavezno, što jasnije definisati opis promena obuhvaćenim komitom. Takođe je bitno da fajlovi koji se komituju budu grupisani u neku celinu. Ovde ponovo dolazi do razlaza sa logikom SVN-a. Komitovanjem se fajlovi ne šalju u centralni repozitorijum već se i dalje čuvaju u okviru našeg radnog direktorijuma. Dakle mi možemo imati više komita pa onda kada završimo neku celinu možemo fajlove poslati u repozitorijum. Fajl ćemo komitovati na sledeći način:

git commit -m "Initial commit"

Odgovor sistema je:

[master (root-commit) 89edc70] Initial commit
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 first.txt

Hajde sada da promenimo sadržaj fajla first.txt. Kada zatražimo status odgovor je sledeći:

# On branch master
# Changes not staged for commit:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#	modified:   first.txt
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	first.txt~
no changes added to commit (use "git add" and/or "git commit -a")

Primećujete kako Git ponovo zahteva da izmenjeni fajl najpre postavimo u pripremni deo a zatim da ga komitujemo. Dakle nije moguće odmah komitovati fajl bez obzira da li je on bio praćen ranije ili ne. Fajl se pre komita mora smestiti u pripremni deo. Kao dodatni parametar u komandi commit možemo proslediti opciju da se fajlovi automatski dodaju u pripremni deo pre samog komita na sledeći način:

git commit -a -m "Second commit"

Snimanje u repozitorijum

Sada kada imamo u našem direktorijumu dva komita želimo da taj sadržaj pošaljemo u repozitorujum kako bi to bilo dostupno i ostalim korisnicima koji ga koriste. To ćemo uraditi preko komande:

git push origin master

Ukoliko budete imali problema sa slanjem izmena na repozitorijum unesite sledeću komandu u folder gde se nalazi repozitorijum (detaljna objašnjenja pogledajte ovde) :

git config --bool core.bare true

Nakon ovoga ponovo pokušajte da pošaljete podatke na repozitorijum.

Preuzimanje iz repozitorijuma

Ukoliko ima još korisnika koji rade nad istim repozitorijumom sledećom komandom bismo preuzeli izmene u naš radni direktorijum:

git pull

Dalji koraci

Ovo je samo prvi u nizu postova o Git-u. Mnogo je još funkcionalnosti i mogućnosti koje treba opisati. Ovo je samo početak, osnova za dalje učenje. Odličan pregled mogućnosti možete pogledati na snimku predavanja Mire Svrtana na nedavno održanom PHP meetup-u u Zagrebu. Sledeći post biće posvećen branch-evima i spajanju istih. Videćete koliko je to jednostavno uraditi koristeći Git.

U skladu sa obećanjem koje sam dao najpre sebi, a i drugima, da ću da naučim da koristim Git ovaj blog post će biti dokaz da sam to i učinio. Ne znam za vas ali za sebe sam poprilično siguran koji ću sistem za verzionisanje koristiti ubuduće.

2 thoughts on “Ko se boji Git-a još

  1. Dusan Lukic say:

    Svaka cast Milane! Jos jedan sjajan clanak koji ce biti koristan mnogima. Bravo!

  2. Rajko Tomic say:

    Hvala puno!

Leave a Reply

Your email address will not be published. Required fields are marked *