Uvod

Tokom razvoja softvera često imamo potrebu da razvoj podelimo na više ljudi. Ovde nastaju problemi sinhronizacije kao i problem kontrole koje su se izmene desile tokom razvoja. Pored ovoga, često se dešava da želimo da se vratimo na prethodnu verziju. Sve ove probleme rešava version control system.

Sistem za kontrolu verzija nam služi da vodimo evidenciju o izmenama, da sinhronizujemo rad na softveru u slučaju kada se softver razvija od strane tima itd. Iako je namenjen za timove, sistem za kontrolu verzija se često koristi i za slučajeve kada se razvoj obavlja samo od strane jedne osobe jer pruža lak način povratka na prethodne verzije.

Sistemi za kontrolu verzija funkcionišu tako što postoji jedan repozitorijum gde se nalazi kod i na njemu se obavljaju sve izmene. Repozitorijum je često direktorijum gde se nalazi kod sa fajlovima.

Po načinu funkcionisanja, sistemi za kontrolu verzija mogu biti centralizovani ili distribuirani. Centralizovani sistemi funkcionišu tako što imamo centralni repozitorijum gde svaki član tima dodaje svoje izmene i sve se dešava na tom centralnom repozitorijumu. Distribuirani sistemi funkcionišu tako što svaki član tima ima svoj repozitorijum i tim funkcioniše tako što se repozitorijumi svakog člana tima sinhronizuju međusobno.

Centralizovani sistemi imaju taj problem što prilikom kvara na serveru gde se nalazi repozitorijum, članovi tima ne mogu da rade na razvoju. Kod distribuiranih sistema se ovaj problem rešava upravo time što svako ima svoju lokalnu verziju repozitorijuma.

Git

Git je sistem za kontrolu verzija koji je slobodan i otvorenog koda (open source). Razvijen je za potrebe razvoja Linuxa i razvio ga je tvorac Linuxa Linus Torvalds. Git je distribuirani sistem što znači da poseduje sve prednosti takvih sistema koje su pomenute iznad. Git je sam po sebi konzolni alat ali postoje softveri koji omogućavaju upotrebu Gita upotrebom grafičkih alata. Radi na Linuxu, Windowsu i OSX a čak postoje i verzije za Android.

Inicijalizacija repozitorijuma

Recimo da \želimo da napravimo naš repozitorijum lokalno, ovo radimo tako što prvo napravimo direktorijum gde ćemo držati naš kod a zatim inicijalizujemo git repozitorijum u njemu.

mkdir repo 
cd repo 
git init

Sada, za svaku promenu u kodu će git beležiti ko ju je napravio. Zbog ovoga je važno da podesimo naše ime i adresu elektronske pošte koja će se pokazati u listi izmena.

git config --global user.name "Pera Perić"
git config --global user.email nasemail@host.com

Operacije nad repozitorijumom

Sada kada smo inicijalizovali naš repozitorijum i rekli git-u ko smo i koji nam je mejl kako bi on znao da zabeleži ispravno ko je uradio određenu izmenu, sada možemo da krenemo sa razvojem softvera.

Dodavanje fajlova

Za početak, treba naglasiti da ako napravimo fajl u našem direktorijumu gde nam je kod, to ne znači da je taj fajl dodat i u repozitorijum. Da dodamo fajl u repozitorijum, koristimo sledeću komandu:

git add imefajla

Sada je fajl dodat u repozitorijum. Isto tako, svaki put kad izmenimo fajl, ako želimo da git prepozna izmene, moramo ga dodati na isti način. Za ovo postoji prečica koju ćemo pomenuti kasnije.

Snimanje izmena

Kada uradimo izmene i kada ih dodamo na repozitorijum sa git add, potrebno je da ih snimimo (komitujemo). Prilikom snimanja izmena, treba da unesemo poruku koja opisuje datu izmenu, na primer ovako:

git commit -m "Popravljen bug #67867"

Ako smo dodali fajlove u repozitorijum, nema potrebe da izmene ponovo dodajemo sa git add već možemo da ih automatski dodamo prosleđivanjem opcije -a u commit komandu:

git commit -a -m "Ispravljen bug #67776"

Isto tako, ako zaboravimo da izmenimo nešto a deo je nekog komita, možemo tu izmenu dodati na poslednji komit sa opcijom –amend

git commit -a --amend

Pregled izmena i diff

Sve izmene koje su se desile možemo pregledati sa git log

git log 

a ako želimo da vidimo šta je izmenjeno za dati komit, koristimo git diff

git diff heš-komita 

Ako želimo da obrišemo nekomitovane promene, koristimo:

git reset --hard 

Da obrišemo poslednji komit i vratimo se na prethodni:

git reset --hard HEAD~1

Grananje

Grananje se upotrebljava kada je potrebno razvijati feature nezavisno od ostalih ili kada se razvijaju dva feature-a nezavisno. Može da posluži i ako želimo da dati problem rešimo na više načina pa da vidimo koji se metod pokazuje bolje. U tom slučaju jednu granu ostavljamo a drugu brišemo. Grananje funkcioniše tako što razvoj razdvojimo na grane i svaka ima svoju istoriju izmena, posle granu spajamo u glavnu granu (master).

Prikaz grananja

Novu granu pravimo ovako:

git checkout -b imenovegrane 

Ovo će napraviti novu granu i prebaciti se na nju. Sada su sve buduće izmene snimaju na novu granu, da menjamo granu, koristimo git checkout

git checkout grana

Glavna grana se zove master pa da se vratimo na nju, radimo:

git checkout master 

Da sve izmene spojimo sa glavnom granom, moramo da uradimo git merge, prvo, pređemo na master granu (ili u neku drugu gde želimo da uradimo spajanje)

git checkout master 
git merge grana 

Da obrišemo granu:

git branch -d grana 

Dobre prakse

Tokom vremena, nastao je dobar model kako organizovati grane i razvoj softvera. Ovo nije must-to-do ali se pokazuje kao jako koristan metod.

Prvo, master grana služi za stabilnu verziju softvera. U njoj se uvek nalazi stabilna verzija softvera. Druga grana je dev u kojoj se nalazi trenutna razvojna verzija softvera. Za svaku novu stavku ili komponentu koju treba implementirati, potrebno je napraviti specijalnu granu za tu stavku. Na primer, ako želimo da implementiramo novu komponentu u GUI-u, recimo iscrtavanje statističkih podataka u nekom prozoru, napravimo granu graphing iz dev grane. Na tome radimo neko vreme i onda radimo merge u dev granu. Kada sve istestiramo i spremni smo da objavimo novu stabilnu verziju, radimo merge dev grane u master. U ovom trenutku ne sme biti grana za dodatne stavke. Kada uradimo merge u master, obavezno kreiramo tag da obeležimo novu verziju:

git checkout master 
git merge dev 
git tag 2.0 

Rad sa remote serverom

Iako je git distribuirani sistem, ;esto imamo potrebu da imamo i neki centralni repozitorijum gde je uvek sve up-to-date. Za ovo možemo koristiti git server i to:

da kloniramo repozitorijum sa remote servera, koristimo git clone

git clone adresa-repozitorijuma 

da uradimo update na lokalni repozitorijum koji je klon sa remote servera:

git pull 

da odradimo update konkretne grane sa servera

git pull grana 

da pošaljemo sve izmene koje smo napravili na server:

git push 

ovo će poslati izmene na master granu, ako želimo poslati izmene na neku drugu granu:

git push grana 

Postoje i servisi koji pružaju usluge git servera za free ili određenu svotu novca u zavisnosti od potreba, na primer GitHub, GitLab itd…