Upload
others
View
6
Download
0
Embed Size (px)
Citation preview
UNIVERZA V MARIBORU
FAKULTETA ZA ELEKTROTEHNIKO,
RAČUNALNIŠTVO IN INFORMATIKO
Robert Tajnšek
IZKUŠNJE PRI VERZIONIRANJU IZVORNE
KODE Z UPORABO SISTEMA GIT
Diplomsko delo
Maribor, avgust 2019
IZKUŠNJE PRI VERZIONIRANJU IZVORNE KODE Z UPORABO SISTEMA
GIT
Diplomsko delo
Študent: Robert Tajnšek
Študijski program: Visokošolski študijski program
Smer: Računalništvo in informacijske tehnologije
Mentor: doc. dr. Matej Črepinšek, unv. dipl. inž. rač. in inf.
Lektorica: Silvia Sambt, mag.
I
Zahvala
Hvala vsem, ki me spremljajo na življenski
poti, za podporo pri padcih in veselju ob
vzponih. Hvala vsem prijateljem za
pomoč, ideje in skupne dogodivščine.
Predvsem bi se rad zahvalil svoji družini za
pomoč, podporo in ljubezen. Velika
zahvala pa gre moji ženi in hčerki za
podporo, ljubezen in potrpljenje.
II
III
Izkušnje pri verzioniranju izvorne kode z uporabo
sistema Git
Ključne besede: Git, GitHub, veja, zapis, sistem za verzioniranje kode
UDK: 004.415.3:004.774(043.2)
Povzetek:
Z izdelavo tega diplomskega dela želimo preko praktičnih primerov skozi osnovne
funkcionalnosti sistema za verzioniranje kode Git. Na koncu bi moral vsakdo imeti
zadostno mero znanja vzpostaviti lokalno okolje z delom z Git.
IV
V
Experiences with the git source code version control
system
Key words: Git, GitHub, branch, commit, version control system
UDK: 004.415.3:004.774(043.2)
Abstract:
Trough this diploma, we want to give practical examples on basic functionalites of the
Git versioning system. In the end, everyone should have sufficient knowledge to establish
a local environment and start working with Git.
VI
VII
KAZALO
1 UVOD ................................................................................................................ 1
2 SISTEM VERZIONIRANJA .................................................................................... 3
2.1 Kratka zgodovina ......................................................................................................... 3
3 NAMESTITEV IN KONFIGURACIJA ....................................................................... 6
3.1 Namestitev Git na Mac OS X ........................................................................................ 6
3.2 Namestitev Git na Linux (Debian/Ubuntu) .................................................................. 6
3.3 Namestitev Git na Windows ........................................................................................ 7
3.4 Konfiguracija ................................................................................................................ 7
4 NASTAVITEV SKLADIŠČA .................................................................................... 8
4.1 Git init .......................................................................................................................... 8
4.2 Git clone ...................................................................................................................... 8
5 SHRANJEVANJE SPREMEMB ............................................................................. 10
5.1 Delovna okolja in HEAD ............................................................................................. 10
5.2 Git status ................................................................................................................... 11
5.3 Git add ....................................................................................................................... 11
5.4 Git commit ................................................................................................................. 11
5.5 Git ignore ................................................................................................................... 11
5.6 Primer uporabe osnovnih ukazov .............................................................................. 13
6 RAZVELJAVLJANJE SPREMEMB ......................................................................... 16
6.1 Git log ........................................................................................................................ 16
6.2 Git reset ..................................................................................................................... 17
6.3 Git revert ................................................................................................................... 19
7 VEJANJE ........................................................................................................... 22
VIII
7.1 Git branch .................................................................................................................. 23
7.2 Git checkout ............................................................................................................... 24
7.3 Git merge ................................................................................................................... 25
7.4 Git rebase ................................................................................................................... 26
7.5 Strategije združevanja vej .......................................................................................... 28
7.5.1 Strategija Fast-forward ...................................................................................................... 28 7.5.2 Strategija Three-way združitev .......................................................................................... 29
7.6 Razreševanje konfliktov ............................................................................................. 30
8 SODELOVANJE ................................................................................................. 32
8.1 Git remote ................................................................................................................. 33
8.2 Git push ...................................................................................................................... 34
8.3 Git fetch ..................................................................................................................... 34
8.4 Git pull ....................................................................................................................... 36
9 POTEKI DELA .................................................................................................... 37
9.1 Centraliziran potek dela ............................................................................................. 38
9.2 Funkcionalni potek dela ............................................................................................. 38
9.3 Potek dela Gitflow ..................................................................................................... 38
9.3.1 Glavni veji ........................................................................................................................... 39 9.3.2 Funkcionalne veje .............................................................................................................. 39 9.3.3 Veje za verzije .................................................................................................................... 40 9.3.4 Popravljalne veje ................................................................................................................ 40
9.4 Upravljalski potek dela .............................................................................................. 40
10 DISTRIBUIRANOST ........................................................................................... 42
10.1 SourceForge ............................................................................................................... 44
10.2 Bitbucket .................................................................................................................... 44
10.3 GitLab ......................................................................................................................... 45
10.4 GitHub ........................................................................................................................ 46
IX
11 GRAFIČNI VMESNIKI ........................................................................................ 48
11.1 SmartGit .................................................................................................................... 48
11.2 SourceTree ................................................................................................................ 49
11.3 GitKraken ................................................................................................................... 50
12 IZKUŠNJE S TERENA ......................................................................................... 52
13 SKLEP ............................................................................................................... 55
X
XI
KAZALO SLIK
Slika 1.1: Primer vizualnega prikaza Git ukaza ................................................................. 2
Slika 4.1: Vizualna reprezentacija ukaza git init ............................................................... 8
Slika 4.2: Vizualna reprezentacija ukaza git clone ........................................................... 9
Slika 5.1: Vizualna reprezentacija primera dodajanja prvega zapisa v skladišče ........... 14
Slika 6.1: Grafičnen prikaz izvedbe ukaza git reset --hard ............................................. 18
Slika 6.2: Grafičen prikaz izvedbe ukaza git revert ........................................................ 20
Slika 7.1: Grafičnen prikaz vejanja v Git skladišču ......................................................... 22
Slika 7.2: Grafičnen prikaz premika izhodiščnega zapisa veje feature ........................... 27
Slika 7.3: Grafičnen prikaz izvedbe fast-forward združevalne strategije ....................... 29
Slika 7.4: Grafični prikaz vej pred združevalno strategijo three-way ............................. 29
Slika 7.5: Grafični prikaz po izvedbi ukaza merge z združevalno strategijo three-way . 30
Slika 8.1: Izmenjava podatkov med lokalnim in oddaljenim skladiščem ....................... 32
Slika 9.1: Primer neorganiziranega vejanja Git skladišča ............................................... 37
Slika 9.2: Primer Gitflow poteka dela ............................................................................ 39
Slika 9.3: Prikaz upravljalskega poteka dela .................................................................. 41
Slika 10.1: Primer distribuiranega skladišča s tremi razvijalci ....................................... 42
Slika 10.2: Logotip storitve za gostovanje Git skladišč Source Forge. ............................ 44
Slika 10.3: Logotip storitve za gostovanje Git skladišč Bitbucket. ................................. 45
Slika 10.4: Logotip storitve za gostovanje Git skladišč GitLab. ...................................... 46
Slika 10.5: Logotip storitve za gostovanje Git skladišč GitHub. ..................................... 46
Slika 10.6: Primer aktivnosti uporabnika za storitve GitHub. Vsak kvadratek predstavlja
dan in bolj je zelen bolj je bil bil uporabnik aktiven oz. več je prispeval k projektom. .. 47
Slika 11.1: Izgled novejše različice programa SmartGit. ................................................ 49
Slika 11.2: Izgled programa SourceTree (različica 1.5). ................................................. 50
Slika 11.3: Izgled različice 6.0.1 programa GitKraken .................................................... 51
Slika 12.1: Primer vejanja in zapisov na začetku projekta Weatherlove ....................... 53
Slika 12.2: Izgled vej in zapisov po uvedbi standardov sporočil in GitFlow poteku dela 54
XII
XIII
KAZALO TABEL
Tabela 2.1: Generacije VCS sistemov ............................................................................... 4
Tabela 5.1: Primeri glob vzorcev katere lahko uporabimo v .gitignore datoteki ........... 13
XIV
XV
SEZNAM UPORABLJENIH KRATIC
VSC - Version control system (Sistem verzioniranja)
SCCS - Source Code Control System (Sistem verzioniranja izvorne kode)
RCS - Revision Control System (Revizijski sistem verzioniranja)
CVCS - Concurrent Versions System (Sistem sočasnih različic)
DVCS - Decentralised Concurrent Versions System (Decentraliziran Sistem sočasnih
različic)
URL - Uniform Resource Locator (Enolični krajevnik vira)
HTTPS - Hypertext Transfer Protocol Secure (varen protokol prenosa informacij na
spletu)
SSH - Secure Sockets Layer
ASCII - American Standard Code for Information Interchange (ameriški standardni nabor
za izmenjavo informacij)
XVI
1
1 UVOD
Za uspešen razvoj programske opreme načeloma potrebujemo dobro razvijalsko ekipo,
ki vsebuje naslednje sestavine: dobro poznavanje programskega jezika, ogrodij, s
katerim dela, ter domenskega znanja za implementacijo rešitev. Vsak takšen sestav pa
potrebuje nek sistem za verzioniranje kode, ki je v današnjem času eksistencialnega
pomena za razumevanje, kaj se dogaja s kodo, za sodelovanje več ljudi na isti bazi kode,
shranjevanje različic, obnavljanje prejšnjih različic ter hitrosti razvoja.
Osebno si ne predstavljam razvoja programske opreme brez vključitve takšnega sistema,
četudi na tem dela samo ena oseba. Situacija se še bolj zaplete, če se tekom razvoja
pridruži več razvijalcev.
Brez takšnega sistema bi morali razvijalci delati v nekašnem direktorju v skupni rabi.
Kričati bi morali po pisarni, da nekdo ureja xyz datoteko in dokler jo ureja, je ne sme
noben drug. Za piko na i lahko dodamo še težave, ki nastopijo, če je vsak razvijalec na
svojem koncu sveta. Takšen potek dela je nesprejemljiv, saj prej ali slej nekdo prepiše
spremembe nekoga drugega.
Poznamo več takšnih sistemov, ampak jaz osebno sem ob prvem projektu, ki smo ga
začeli s prijatelji tekom študija, začel uporabljati Git.
V nadaljevanju diplomskega dela bom predstavil, kaj je sistem verzioniranja, osnovna
delovanja sistema Git, storitve in programe, ki so se razvili okoli Gita ter nekaj praktičnih
primerov uporabe, ki temeljijo na izkušnjah pridobljenih tekom deset in več let razvoja
programskih rešitev.
Pri primerih bom prikazal, kako uporabljati Git ukaze v ukazni vrstici oziroma terminalu.
Prikazal bom, kakšen ukaz je potrebno pognati ter kaj nam ta ukaz izpiše. Vse to bo
vizualno ločeno v črnem okvirju, kjer vsak ukaz predstavlja vrstico, ki se začne s
simbolom dolar $. Vrstice, ki se ne začnejo s tem simbolom, predstavljajo izpis ukaza.
Takšen primer bo zgledal nekako takole:
2
$ git --version git version 2.21.0
Ker pa iz prakse vem, da se veliko ljudi boji uporabljati terminal, bom poleg določenih
primerov za terminal dodal vizualno prezetacijo, kaj se dogaja, ko poženemo določen
ukaz. Primer tega bo zgledal, kot je prikazano na sliki 1.1.
Slika 1.1: Primer vizualnega prikaza Git ukaza
master
git clone
Initia
l commit
5rcd2
82
UkazSkladišče
Veja
Zapis
Sporočilo in identifikator zapisa
Oddaljeno skladišče
3
2 SISTEM VERZIONIRANJA
Ko govorimo o sistemu verzioniranja (v nadaljevanju VCS), govorimo o kategoriji
programskih orodij, ki nadzirajo spremembe nad dokumenti ali drugimi zbirkami
podatkov. Za razvoj programskih orodij se uporablja sledenje in upravljanje sprememb
izvorne kode, kar pomaga ekipam programske opreme boljše obvladovati spremembe
skozi čas. Če pride do napake, lahko razvijalci primerjajo starejše različice izvorne kode
in s tem popravijo napako ter zmanjšajo motnje za vse člane razvojne skupine.
Razvijalci programske opreme, ki delajo v skupinah, stalno dodajajo in spreminjajo
obstoječo izvorno kodo. Nek razvijalec lahko dela na novi funkcionalnosti, medtem ko
drug popravlja nepovezano napako. Vsak razvijalec lahko izvede spremembe v več
datotekah. VCS pomaga pri sledenju sprememb in preprečuje, da bi bile spremembe v
sporu. Spremembe, izvedene v enem delu programske opreme, so lahko nezdružljive s
tistimi, ki jih je naredil drug razvijalec na istem delu. To težavo je treba odkriti in rešiti
na urejen način, ne da bi blokirali delo preostale ekipe.
Ko se navadimo na sistem verzioniranja in prepoznamo izjemne prednosti, si težko
predstavljamo razvoj programske opreme brez sistema.
2.1 Kratka zgodovina
Posplošeno lahko VCS sisteme delimo na tri generacije (tabela 2.1).
Generacija Mreženje Operacije Primer
Prva brez ena
datoteka
naenkrat
RCS, SCCS
Druga centralizirano več datotek
naenkrat
CVS, SourceSafe, Subversion, Team
Foundation Server
4
Tretja distribuirano nabor
sprememb
Bazaar, Git, Mercurial
Tabela 2.1: Generacije VCS sistemov
Prvi VCS sistem imenovan SCCS (Source Code Control System) je razvil Bell Labs leta
1972. Delal je samo na UNIX platformi in samo z datotekami izvorne kode. Deset let
kasneje se je razvil RCS (Revision Control System), ki je delal na različnih platformah. Oba
sistema nista bila narejena za deljenje in sta delala samo na lokalnem razvojenm okolju
za enega posameznega razvijalca.
Druga generacija se je začela leta 1986 z VCS sistemom CVS (Concurrent Versions
System). Uporabljal je centralizirano skladišče za verzioniranje (CVCS), katerega je lahko
uporabljalo več razvijalcev in so tako lahko lažje delili delu. Kasneje, v osemdesetih, je
na obzorje prišel Perforce, ki je do danes še vedno največje skladišče znotraj podjetja
Google. Leta 2000 je prišel Subversion, ki je podpiral netekstovne datoteke, zaznaval
spremembe znotraj direktorijev, kot so preimenovanje in premikanje datotek. 2004 je
Microsoft naredil TFS (Concurrent Versions System). Ne samo da je TFS sledil
spremembam datotek, ampak je imel vgrajeno tudi sledenje hroščev in dela ter
funkcionalnost za avtomatsko testiranje.
Naslednja, tretja generacija, v kateri smo še vedno, je prinesla distribuiran sistem za
verzioniranje oziroma DVCS (Distributed Version Control System). Razlikuje se v tem, da
skladišče ni na enem centralnem strežniku, s katerim manipulirajo razvijalce, ampak
lahko ima vsak razvijalec svojo kopijo celotnega skladišča. Se pravi DVCS omogoča, da
imamo isto skladišče na več računalnikih. Omogoča tudi, da imamo več instanc istega
skladišča na enem ali več računalnikih. Konec koncev je potrebno skladišče sinhronizirati
in spremembe uskladiti, za kar se ponavadi uporablja nek centralen server. V praksi ima
vsaka razvijalska ekipa, ki uporablja DVCS, en centralen server.
5
Linus Torvalds je v času med letom 2002 in 2005, ko je s skupino ljudi delal na Linux
kernelu, uporabljal CVCS orodje BitKeeper. Program je bil brezplačen, ampak je podjetje
leta 2005 spremenilo licence in tako so vsi produkti bili komercialni. Linus in nekaj ostalih
razvijalcev Linux kernela tega niso odobravali, ker so želeli, da bo vse povezano z
Linuxom brezplačno. Temu primerno je Linus Torvalds naredil enega izmed prvih DVCS
sistemov imenovan Git. Konkurenčni odprtokodni izdelek Mercurial je bil prav tako
ustvarjen leta 2005 kot odgovor na isto spremembo BitKeeper licenciranja.
Pred Git in Mercurial sistemoma je bilo še nekaj odprtokodnih DVCS sistemov, kot na
primer Arch, Monotone, and Darcs vendar so postali priljubljeni šele po objavi Git in
Mercurial.
Dandanes se v večini uporablja enega od petih večjih VCS sistemov. Perforce,
Subversion/SVN ali TFS, če ekipe želijo centraliziran sistem, Git ali Mercurial, če želijo
distribuiran sistem.
6
3 NAMESTITEV IN KONFIGURACIJA
Da lahko začnemo uporabljati Git moramo zagotoviti, da ga imamo nameščenega na
svojem sistemu. V določenih primerih je lahko Git že nameščen, kar lahko preverimo z
zagonom naslednjega ukaza v ukazni vrstici:
$ git –-version
Če se nam v ukazni vrstici izpiše nekaj podobnega, kot je navedeno spodaj, imamo na
sistemu nameščen Git.
git version 2.21.0
V nasprotnem primeru bo potrebno skozi postopek namestitve, ki je za vsak operacijski
sistem drugačen.
3.1 Namestitev Git na Mac OS X
Na računalnik prenesemo namestitveni paket, ki se nahaja na spletni strani
https://sourceforge.net/projects/git-osx-installer/files/. Po prenosu ga zaženemo in
sledimo navodilom namestitve. Po namestitvi lahko preverimo, če je bila uspešna z
zagonom ukaza v ukazni vrstici:
$ git –-version
3.2 Namestitev Git na Linux (Debian/Ubuntu)
Git paketi so na voljo preko apt (Advanced Package Tool). V ukazni vrstici zaženemo:
$ sudo apt-get update $ sudo apt-get install git
7
3.3 Namestitev Git na Windows
Na računalnik prenesemo namestitveni paket, ki se nahaja na spletni strani
https://gitforwindows.org/. Po prenosu ga zaženemo in sledimo navodilom namestitve.
Po namestitvi lahko preverimo, če je bila uspešna z zagonom ukaza v ukazni vrstici:
$ git –-version
3.4 Konfiguracija
Ko imamo Git uspešno nameščen na sistemu, si je potrebno nastaviti uporabniško ime
in email, katera bosta asociirana z vsakim zapisom v Git zgodovino. To si nastavimo z
naslednjim ukazom:
$ git config --global user.name "Robert Tajnšek" $ git config --global user.email "[email protected]"
8
4 NASTAVITEV SKLADIŠČA
Skladišče lahko ustvarimo na dva načina. Ali ga ustvarimo čisto na novo ali pa že
obstoječo skladišče kloniramo iz centraliziranega skladišča in s tem dobimo lokalno
kopijo. V naslednjih dveh podpoglavjih bom opisal vsako metodo posebej.
4.1 Git init
Če želite ustvariti novo skladišče, se najprej postavite v direktorij, katerega želite
verzionirati in uporabite ukaz git init.
$ cd /projects/hobby-project $ git init Initialized empty Git repository in /projects/hobby-project /.git/
Slika 4.1: Vizualna reprezentacija ukaza git init
Je enkratni ukaz, ki ga uporabite za začetno nastavitev novega skladišča. Zagon tega
ukaza bo v trenutnem delovnem direktoriju ustvaril nov poddirektorij .git in glavno vejo
(master). Vizualni primer tega ukaza je prikazan na sliki 4.1.
4.2 Git clone
Če skladišče že obstaja v nekem centraliziranem skladišču (naprimer GitHub ali
Bitbucket), je ukaz za kloniranje najpogostejši način, s katerim lahko pridobimo lokalno
master
git init
9
kopijo za razvoj. Tako kot git init je kloniranje običajno enkratna operacija. Pri
izvedbi ukaza je potrebno navesti URL do centraliziranega skladišča.
$ git clone https://github.com/ronzyfonzy/hobby-project
Slika 4.2: Vizualna reprezentacija ukaza git clone
Izvedba zgornjega ukaza bo naredila nov lokalni direktorij hobby-project in vanj prenesla
kopijo oziroma klon iz GitHub centraliziranega skladišča (slika 4.2). Git podpira različne
mrežne protokole kot so HTTPS in Git SSH. Za zgornji ukaz smo uporabili HTTPS protokol.
Git SSH protokol zgleda takole:
$ git clone [email protected]:ronzyfonzy/hobby-project.git
master
git clone
Initia
l commit
5rcd2
82
10
5 SHRANJEVANJE SPREMEMB
Pri Git in ostalih sistemih verzioniranja je koncept shranjevanja sprememb malce
drugačen od tradicionalnega shranjevanja preko urejevalnikov datotek. Če pri
tradicionalnih urejevalnikih datotek ob shranjevanje prepišemo celotno datoteko, se pri
Git operaciji, shranjevanje izvrši nad datotekami in direktoriji. Operacijo shranjevanja pri
Git imenujemo »commit«. Z izvrševanjem kombinacije ukazov git add, git commit,
git status v skladišče dodamo zapise sprememb, nastalih od prejšnjega stanja
datotek in direktorijev. Git teh zapisov ne bo nikoli spreminjal, razen če tega izrecno ne
izvršimo. Omenjeni trije ukazi so temeljni za delo z Git in jih mora razumeti vsak
uporabnik.
V nadaljevanju bodo opisani osnovni ukazi in koncepti za delo z Git skladiščem. Na koncu
poglavja pa bomo dodali še praktičen primer uporabe teh ukazov.
5.1 Delovna okolja in HEAD
Pomemben koncept, ki ga je potrebno omeniti, je delovno in staging okolje. Ko naredimo
spremembo v eni izmed datotek, ki jih verzioniramo, se te spremembe avtomatsko
dodajo v delovno okolje. Ko končamo z urejanjem datotek, moramo Gitu nakazati, kaj
želimo dodati k zapisu v skladišče. To naredimo tako, da izvršimo ukaz git add in
prestavimo spremembe iz delovnega okolja v staging okolje. Staging okolje je unikatna
funkcionalnost Git sistema, ki služi kot zadnji korak oziroma pregled, kaj bomo dodali v
naslednji zapis oz. commit.
V nadaljevanju se bo pojavljal pojem HEAD. To je sklic oziroma referenca na vejo, katera
je trenutno aktivna. Ukazi, ki jih bomo izvajali, se bodo aplicirali na aktivno vejo. To vejo
lahko identificiramo preko git log ukaza, katerega bomo opisali kasneje.
11
5.2 Git status
S tem ukazom prikažemo stanje delovnega in staging okolja. Omogoča pregled, katere
datoteke so bile spremenjene, katere so bile dodane v staging okolje in katere datoteke
Git še ne spremlja.
5.3 Git add
Ukaz git add doda spremembe iz delovnega okolja v tako imenovanlo »staging«
okolje. S tem ne naredimo nobene bistvene spremembe v skladišču, ampak Gitu
nakažemo, da želimo spremembe, ki so v »staging« okolju, dodati v naslednji
zapis/commit.
5.4 Git commit
Kot omenjeno, se pri izvršitvi ukaza git commit v skladišče doda nov zapis stanja
spremenjenih datotek, ki so v staging okolju. S tem ko naredimo več commitov v
skladišče, si ustvarjamo časovnico sprememb posameznih datotek.
Git bo po privzetem delovanju ob izvršitvi ukaza commit odprl privzeti urejevalnik
besedila v konzoli, preko katerega bomo dodali sporočilo. Običajna praksa teh sporočil
je, da v prvo vrstico vpišemo ključno zadevo spremembe (kot zadeva pri email sporočilu).
Preostali del sporočila pa se obravnava kot dodatna razlaga o spremembah v zapisu.
Če želimo preskočiti, da nam odpira urejevalnik besedil, lahko poleg ukaza dodamo
zastavico -m in zatem vpišemo zadevo za sporočilo.
$ git commit -m "My first commit"
5.5 Git ignore
Git predvideva, da je vsaka datoteka znotraj delovnega direktorija v enem od treh stanj:
- spremljana: datoteka, ki je bila dodana v staging okolje ali je bila že zapisana v
skladišče;
12
- nespremljana: datoteka, ki še ni bila zapisana v skladišče ali dodana v staging
okolje;
- ignorirana: datoteka, za katero je bilo eksplicitno zapisano, da ji Git ne sme
slediti.
Ignorirane datoteke so ponavadi datoteke, ki jih ne želimo verzionirati. Nekaj primerov
takšnih datotek so:
- pomnilniški direktorij za odvisne pakete (dependency cache), kot na primer
node_modules (node.js npm) ali vendor (PHP composer);
- direktoriji za zgrajeno kodo, kot so /bin ali /out;
- skrite datoteke, kot so .DS_Store ali Thumbs.db;
- konfiguracijske datoteke urejevalnikov, kot na primer .vscode ali
.idea/workspace.xml.
Če želimo specifične datoteke ignorirati, moramo narediti zapis v posebno datoteko z
imenom .gitignore. Ko to datoteko naredimo, jo moramo tako kot vse ostale zapisati v
skladišče, če želimo da začne Git upoštevati navedena ignoriranja. Če se kasneje pojavijo
datoteke, ki jih želimo dodatno ignorirati, enostavno dodamo zapis v .gitignore datoteko
in naredimo novi zapis v skladišče. V .gitignore datoteko lahko dodajamo zapise z glob
vzorci (kombinacija alfanumeričnih znakov in simbolov za iskanje datotek), s katerimi
nakažemo, katere datoteke želimo ignorirati. Nekaj primerov teh vzorcev je navedenih
v tabeli 5.1.
Vzorec Primer ujemanja
**/logs logs/debug.log
logs/ponedeljek/foo.bar
build/logs/debug.log
*.log
!important.log
debug.log
trace.log
13
ampak ne ignorira
important.log
logs/important.log
debug.log debug.log
logs/debug.log
logs/*ek/debug.log logs/ponedeljek/debug.log
logs/torek/debug.log
ampak ne ignorira
logs/sreda/debug.log
Tabela 5.1: Primeri glob vzorcev katere lahko uporabimo v .gitignore datoteki
5.6 Primer uporabe osnovnih ukazov
Spodaj je prikazan praktični primer uporabe osnovnih ukazov za Git. S spodnjimi ukazi
bomo inicializirali Git v izbranem direktoriju, dodali dve datoteki in izpisali status Gita.
Vizualizacija primera je prikazana na sliki 5.1.
14
Slika 5.1: Vizualna reprezentacija primera dodajanja prvega zapisa v skladišče
$ cd /projects/my-project $ git init Initialized empty Git repository in /projects/hobby-project/.git/ $ echo "My first text" > file-1.txt $ echo "My second text" > file-2.txt $ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) file-1.txt file-2.txt nothing added to commit but untracked files present (use "git add" to track)
git initmastergit add .
mastergit commit -m "My first commit"
My first
commit
cecd
282
15
Po izvedbi ukaza git status nam git sporoča, da smo na master veji, da ni še nobenega
zapisa oz commita in da imamo dve nespremljani datoteki. Sedaj bomo ti dve datoteki
dodali na staging okolje in naredili zapis ter ponovno izpisali status. Na koncu ukaza git
add smo dodali piko, kar pomeni, da bomo iz delovnega okolja v staging okolje dodali
vse datoteke (v našem primeru file-1.txt in file-2.txt).
$ git add . $ git commit -m "My first commit" [master (root-commit) cecd282] My first commit 2 files changed, 2 insertions(+) create mode 100644 file-1.txt create mode 100644 file-2.txt $ git status On branch master nothing to commit, working tree clean
Ko smo pognali ukaz status, nam Git sporoča, da nimamo nobenih sprememb v
delovnem okolju.
16
6 RAZVELJAVLJANJE SPREMEMB
Tako kot koncept shranjevanja sprememb v Git je razveljavljanje sprememb drugačno
od tradicionalih urejevalnikov datotek. Git v ta namen uporablja ukaze kot so
git revert in git reset.
Za lažjo predstavo si lahko predstavljamo, da je Git kot nekakšen upravljalec sprememb
po časovni premici. Vsak zapis je točka v času, ko se je naredila relevantna sprememba
v projektu. Poleg tega imamo lahko več časovnih premic v obliki vej (branch). Kadar
želimo razveljavljati spremembe, se ponavadi premaknemo nazaj v čas ali na drugo
časovno premico.
V nadaljnih podpoglavjih bomo opisali zgoraj omenjena ukaza ter kako lahko
pregledujemo zgodovino zapisov s pomočjo ukaza git log.
6.1 Git log
Namen vsakega sistema verzioniranja je nadzor različic in beleženje sprememb datotek.
To nam daje osnovo, da lahko naredimo zgodovinski pregled nad tem, kdaj je kdo kaj
spreminjal v projektu. Ampak vsa ta zgodovina je neuporabna, če ne znamo navigirati
skozi njo. Ukaz git log nam ravno to omogoča. Na kratko si bomo pogledali različne
načine izpisov in katere informacije ti izpisi prikazujejo.
Za začetek poženimo ukaz z zastavico --oneline, kjer vsaka vrstica v izpisu predstavlja
en zapis. Zapisi si sledijo od najnovejšega do najstarejšega od zgoraj navzdol:
$ git log --oneline c198ba6 (HEAD -> master) Replaced word awes 7c0ed82 Merge branch 'feature/add-new-file' 3cdd142 (feature/add-new-file) Updated file 98386e8 Added file 3 a93e671 Added .gitignore file 32497b0 My second commit cecd282 My first commit
17
Vsak zapis pridobi unikaten SHA-1 identifikator. S pomočjo teh identifikatorjev se lahko
prestavljamo po zgodovini Git. Poleg indetifikatorja in sporočila dobimo tudi reference
določenih zapisov (kje se nahajajo veje in podobno, npr. (master)) ter informacijo,
katera je trenutno aktivna veja z indeksom HEAD. Privzeto nam ukaz prikaže zapise s
trenutno izbrane veje. Če poženemo ukaz brez dodatnih zastavic, dobimo podrobnejše
informacije za vsak zapis. Primer takšnega izpisa je sledeč:
$ git log create mode 100644 file-3.txt commit c198ba67c641f9ba6c474ecf9bb3804644ce6b15 Author: Robert Tajnšek <[email protected]> Date: Sun Jun 9 18:48:03 2019 +0200 Replaced word awesome in file 3
Za malce bolj grafičen prikaz zapisov pa lahko uporabimo --graph zastavico, kjer nam
izpise ASCII graf, ki prikaže strukturo vej in zgodovino zapisov.
$ git log --graph --oneline * c198ba6 (HEAD -> master) Replaced word aw * 7c0ed82 Merge branch 'feature/add-new-f |\ | * 3cdd142 (feature/add-new-file) Updated | * 98386e8 Added file 3 |/ * a93e671 Added .gitignore file * 32497b0 My second commit * cecd282 My first commit
Sedaj ko vemo, kako pregledovati zgodovino zapisov, lahko z ukazoma git revert in
git reset razveljavimo izbrane spremembe s pomočjo indentifikatorjev zapisov.
6.2 Git reset
Vsestranski ukaz za razveljavljanje sprememb v Git je git reset. Ta ukaz uporabimo,
ko želimo trenutno vejo ponastaviti v drugo stanje. Pri tem moramo kot dodatni
argument dodati indentifikator zapisa, v katerega želimo, da ponastavimo stanje. Poleg
18
tega lahko dodamo določene zastavice, s katerimi povemo, kaj naj Git naredi s
spremembami v zapisih, ki jih razveljavljamo:
- --hard: ponastavi HEAD na izbran zapis in odstrani vse spremembe. S to
zastavico izgubimo vse spremembe iz ponastavljenih zapisov kot tudi
spremembe, ki so v delovnem in staging okolju.
- --mixed: privzet način reset ukaza. Ponastavi HEAD na izbran zapis. Vse
spremenjene datoteke iz zapisov ohrani in jih doda v delovno okolje. Tako so te
spremenjene datoteke pripravljene na nov zapis.
- --soft: ponastavi HEAD na izbran zapis. Podobno kot --mixed ohrani vse
spremenjene datoteke iz zapisov in jih doda v staging okolje. Datoteke, ki pa so
bile v delovnem okolju, pa ohrani tam.
Slika 6.1: Grafičnen prikaz izvedbe ukaza git reset --hard
Poglejmo si primer razveljavljanja z --hard zastavico. Naredili bomo eno spremembo
in jo zapisali v Git s sporočilom »Bad commit«.
$ echo "Some text" >> file-1.txt $ git add file-1.txt $ git commit -m "Bad commit" [master 8a1ad6c] Bad commit 1 file changed, 1 insertion(+)
Sedaj s pomočjo ukaza git log izpišemo zgodovimo zapisov:
19
$ git log --oneline 8a1ad6c (HEAD -> master) Bad commit c198ba6 Replaced word awesome in file 3 7c0ed82 Merge branch 'feature/add-new-file' 3cdd142 (feature/add-new-file) Updated file 98386e8 Added file 3
Preko izpisa vidimo, da HEAD kaže na zapis z identifikatorjem 8a1ad6c. Ta zapis želimo
razveljaviti na prejšnje stanje z identifikatorjem c198ba6. Zatem poženemo še ukaza
git status in git log ter si poglejmo izpis. Vizualna reprezencatija ukaza je
prikazana na sliki 6.1.
$ git reset --hard c198ba6 HEAD is now at c198ba6 Replaced word awesome in file 3 $ git status On branch master nothing to commit, working tree clean $ git log --oneline c198ba6 (HEAD -> master) Replaced word awes 7c0ed82 Merge branch 'feature/add-new-file' 3cdd142 (feature/add-new-file) Updated file 98386e8 Added file 3
Po zagonu ukaza reset vidimo, da sedaj nimamo več zapisa »0ab860c Bad commit«, kar
pomeni, da smo izgubili vse spremembe narejene v tistem zapisu. Če bi želeli ohraniti
spremembe, bi lahko pognali ukaz reset z zastavico --soft ali --mixed.
6.3 Git revert
Ukaz git revert je kot git reset ukaz za razveljavljanje sprememb z razliko, da ne
izgubimo nobenih zapisov. Namesto da zapise odstranimo, Git preračuna inverz
sprememb izbranega zapisa in to doda v shrambo. Poglejmo si primer uporabe ukaza
kot je prikazano na sliki 6.2.
20
Slika 6.2: Grafičen prikaz izvedbe ukaza git revert
Naredili bomo dva zapisa. Prvi bo vseboval sporočilo »Bugfix on file 1« drugi pa »Another
commit«.
$ echo "Fixed a bug" >> file-1.txt $ git add file-1.txt $ git commit -m "Bugfix on file 1" [master 19eb46f] Bugfix on file 1 1 file changed, 1 insertion(+) $ echo "Added some text" >> file-2.txt $ git add file-2.txt $ git commit -m "Another commit" [master ac5f72e] Another commit 1 file changed, 1 insertion(+)
Sedaj s pomočjo ukaza git log izpišemo zgodovimo zapisov:
$ git log --oneline ac5f72e (HEAD -> master) Another commit 19eb46f Bugfix on file 1 c198ba6 Replaced word awesome in file 3 7c0ed82 Merge branch 'feature/add-new-file' 3cdd142 (feature/add-new-file) Updated file 98386e8 Added file 3
Če želimo ponastaviti spremembe, ki smo jih naredili z zapisom 19eb46f, moramo
uporabiti ukaz revert:
21
$ git revert 19eb46f [master 025ead1] Revert "Bugfix on file 1" 1 file changed, 1 deletion(-)
Z izvedbo ukaza revert je Git preveril spremembe, ki so bile narejene z zapisom
19eb46f, izračunal inverz teh sprememb in naredil nov zapis, kateri razveljavi te
spremembe. Na koncu si lahko ogledamo, kako izgleda izpis zgodovine.
$ git log --oneline 025ead1 (HEAD -> master) Revert "Bugfix on ac5f72e Another commit 19eb46f Bugfix on file 1 c198ba6 Replaced word awesome in file 3 7c0ed82 Merge branch 'feature/add-new-file' 3cdd142 (feature/add-new-file) Updated file 98386e8 Added file 3
22
7 VEJANJE
Vejanje oziroma ang. branching je najbolj močan del modernih sistemov za
verzioniranje. S pravim pristopom upravljanja vej dosežemo abstraktnost razvoja kode,
lažje delo razvijalcev ter posledično večjo hitrost objave novih različic programa, ki ga
razvijamo.
V določenih sistemih verzioniranja je vejanje zahtevna operacija v smislu časa zajema
prostora na disku. V Gitu pa so veje zgolj kazalci na posnetke sprememb in predstavljajo
neodvisno linijo razvoja kode. Ko v kodi želimo odpraviti napako ali razviti novo
funkcionalnost, enostavno naredimo novo vejo, kamor zapisujemo vse relevantne
spremembe. S tem načinom imamo nadzor nad tem, da v glavno vejo razvoja ne pridejo
nestabilne spremembe.
Slika 7.1: Grafičnen prikaz vejanja v Git skladišču
master
feature #1
feature #2
23
Zgornja slika (7.1) prikazuje primer skladišča, ki ima tri veje razvoja. Ne samo da nam ta
način omogoča paralelni razvoj na obeh feature vejah, temveč tudi obvaruje glavno
master vejo pred nedokončano ali nepreverjeno kodo, preden se te združijo vanjo.
V nadaljevanju bomo opisali ukaze, s katerimi upravljamo veje v Gitu.
7.1 Git branch
Ukaz git branch nam omogoča izpisovanje, kreiranje, preimenovanje in brisanje vej.
Primer izvedbe posameznega ukaza si poglejmo v naslednjih primerih.
Za izpis vseh lokalnih vej uporabimo ukaz git branch. Ukaz je ekvivalent ukazu
git branch --list. Izpis nam s simbolom – zvezdico prikaže, katero vejo imamo
trenutno izbrano. Za izpis vseh vej (vključno z oddaljenimi) uporabimo zastavico -a. Če
pa želimo izpisati samo oddaljene veje,pa uporabimo zastavico -r.
$ git branch feature/add-new-file feature/new-lines * master
Novo vejo ustvarimo z ukazom git branch <ime_veje>.
$ git branch test-branch
Preimenovanje veje izvedemo z zastavico -m. V mislih je potrebno imeti, da s tem
preimenujemo trenutno aktivno vejo.
$ git branch -m test-rename-branch
Za brisanje veje dodamo zastavico -d. To je varen način brisanja, saj Git prepreči, da bi
izbrisali vejo, katera ima še nezdružene spremembe. Če želimo vejo izbrisati ne glede na
nezdružene spremembe, uporabimo zastavico -D.
24
$ git branch -d test-rename-branch error: The branch 'test-rename-branch' is not fully merged. If you are sure you want to delete it, run 'git branch -D test-rename-branch'. $ git branch -D test-rename-branch Deleted branch test-rename-branch (was 1bd2e2a).
7.2 Git checkout
Za navigacijo med vejami, ki smo jih ustvarili z ukazom git branch, uporabljamo ukaz
git checkout. Ko izvedemo ta ukaz in se preklopimo na drugo vejo, Gitu povemo, da
od tega trenutka dalje vse nove zapise shranjujemo v to vejo. Poglejmo si primer
zamenjave veje.
Najprej izpišemo vse lokalne veje, zamenjamo vejo in ponovno izpišemo vse lokalne
veje.
$ git branch feature/add-new-file feature/new-lines * master $ git checkout feature/new-lines Switched to branch 'feature/new-lines' $ git branch feature/add-new-file * feature/new-lines master
Razvidno iz prvega in drugega git branch ukaza, se je zamenjala aktivna veja iz master
na feature/new-lines, kar nakazuje simbol zvezdica.
S pomočjo zastavice -b lahko hkrati kreiramo in preklopimo vejo. To je priročna metoda,
ki pred preklopom na vejo izvede ukaz git branch za kreiranje nove veje.
$ git checkout -b new-branch Switched to a new branch 'new-branch' $ git branch feature/add-new-file feature/new-lines master * new-branch
25
Privzeto bo Git naredil novo vejo iz trenutno aktivne veje. Opcijsko lahko kot dodaten
argument k ukazu Gitu povemo, iz katere veje naj naredi novo vejo.
$ git checkout -b new-branch feature/new-lines Switched to a new branch 'new-branch'
7.3 Git merge
Ko ustvarjamo nove veje, jih želimo v neki točki združiti nazaj v glavno. To združevanje
dosežemo z ukazom git merge.
Potrebno je vedeti, da ob izvedbi ukaza združujemo spremembe v aktivno vejo. Aktivna
veja bo s tem dobila spremembe iz tiste, ki jo želimo združiti, medtem ko le-ta ne bo
spremenjena. Spremljevalni ukazi h git merge so s tem git checkout, da izberemo
aktivno vejo (vejo, v katero želimo združiti spremembe) in git branch -d da vejo, ki
je bila združena, zbrišemo.
Praktično gledano ob zagonu ukaza bo Git pogledal konici dveh vej in poiskal zapis, iz
katerega imata obe veji skupno izhodišče. Ko Git najde skupno izhodišče, bo izbral
združevalno strategijo, s katero bo združil veji in zapise v njima. Pred zagonom
git merge ukaza moramo zagotoviti, da nimamo nobenih neshranjenih sprememb in
da smo na pravi aktivni veji. V nasprotnem primeru uporabimo ukaz git checkout,
da se prestavimo na vejo, v katero želimo združiti spremembe. Vizualni primer bomo
prikazali v poglavju združevalnih strategij.
Predvidevajmo, da imamo vejo new-feature z dvema novima zapisoma. Sedaj jo želimo
združiti v vejo master. Poglejmo situacijo s pomočjo git log ukaza:
26
$ git log --graph --oneline --all * 81398b5 (master) Edit in file 1 | * dd8ce1e (new-feature) Fix on new featur | * 6f1f925 Commit on new feature |/ * 025ead1 Revert "Bugfix on file 1 * ac5f72e Another commit
Sedaj se prestavimo na vejo master, poženemo git merge ukaz z vejo new-feature in
izpišemo spremembe z git log ukazom:
$ git checkout master $ git merge new-feature Merge made by the 'recursive' strategy. file-3.txt | 3 +++ 1 file changed, 3 insertions(+) $ git log --graph --oneline --all * a882694 (master) Merge branch 'new-feature' |\ | * dd8ce1e (new-feature) Fix on new feature | * 6f1f925 Commit on new feature * | 81398b5 Edit in file 1 |/ * 025ead1 Revert "Bugfix on file 1 * ac5f72e Another commit
Po merge ukazu vidimo, da se je veja new-feature združila z vejo master preko
združevalnega zapisa z identifikatorjem a882694.
7.4 Git rebase
S pomočjo ukaza git rebase integriramo spremembe ene veje na vrh druge veje. Z
drugimi besedami Git vzame izhodiščni zapis veje in ga prestavi na drug zapis.
27
Slika 7.2: Grafičnen prikaz premika izhodiščnega zapisa veje feature
Glavni namen uporabe tega ukaza je, da ohranimo linearno strukturo zapisov v
skladišču, kot je prikazano na sliki 7.2. Primer uporabe bi bil sledeč:
Smatrajmo, da smo iz master veje začeli novo vejo feature. Tekom razvoja in dodajanja
zapisov na vejo feature smo dodajali spremembe tudi na vejo master. Sedaj imamo
situacijo, kjer ima master spremembe, ki jih nimamo v feature. Če želimo dobiti te
spremembe na vejo feature, je ena izmed možnosti uporaba git rebase ukaza, kjer
Gitu ukažemo, da mora vejo feature postaviti na vrh veje master. Najprej lahko
preverimo, kakšno imamo strukturo zapisov z izvedbo git log ukaza.
$ git log --graph --oneline --all * 7679f9e (master) Commit #1 on master | * 8e20c0e (feature) Commit #2 on feature | * 721bbf2 Commit #1 on feature |/ * fe17899 (ghub/master) Updated file 3 * 1e866d1 Merge branch 'conflict-test
Iz izpisa je razvidno, da ima veja master en novejši zapis od veje feature. Sedaj se
postavimo na vejo feature in poženemo ukaz git rebase <veja>,kjer <veja>
zamenjamo z vejo, na vrh katere želimo, da bo veja feature izhajala.
master
feature feature
28
$ git checkout feature Switched to branch 'feature' $ git rebase master First, rewinding head to replay your work on top of it... Applying: Commit #1 on feature Applying: Commit #2 on feature
Če ponovno poženemo git log ukaz, bomo videli, da smo vejo feature postavili na vrh
veje master.
$ git log --graph --oneline --all * 56c6b5e (feature) Commit #2 on feature * 2544a3b Commit #1 on feature * 7679f9e (master) Commit #1 on master * fe17899 (ghub/master) Updated file 3 * 1e866d1 Merge branch 'conflict-test'
7.5 Strategije združevanja vej
Git nam omogoča različne načine, kako lahko združimo veje. Na podlagi stanja in pozicij
vej bo Git avtomatsko preračunal optimalno strategijo združevanja. To pa lahko
določimo tudi sami. Lasten izbor združevalne strategije je ponavadi preferenca
uporabnika, kako želi prikazati in ohraniti zgodovino zapisov.
Obstaja kar nekaj načinov združitve vej, v nadaljevanju bomo opisali najbolj pogoste.
7.5.1 Strategija Fast-forward
Fast-forward združitev se zgodi, ko imamo linearno pot od aktivne veje do ciljne veje
(katero želimo združiti). Namesto da Git naredi nov združevalni zapis, samo pomakne
aktivno vejo do ciljne veje, kot je prikazano na sliki 7.3.
Ta način združevanja ni mogoč, če se veji razlikujeta oziroma imata nove zapise iz
skupnega izhodišča. Git v tem primeru nima druge možnosti, kot da ju združi preko
three-way združitve.
29
Slika 7.3: Grafičnen prikaz izvedbe fast-forward združevalne strategije
7.5.2 Strategija Three-way združitev
Predstavljajmo si, da imamo primer z master in feature vejo (slika 7.4) ter želimo slednjo
združiti v master vejo.
Slika 7.4: Grafični prikaz vej pred združevalno strategijo three-way
master
feature
master
master
feature
skupno izhodišče
30
Izvedba ukaza git merge uporabi three-way združevalno strategijo in združi
spremembe iz feature veje v aktivno vejo (predpostavljamo, da je to master) in nanjo
naredi nov zapis (slika 7.5).
Slika 7.5: Grafični prikaz po izvedbi ukaza merge z združevalno strategijo three-way
Združevalni zapis je unikaten v primerjavi z navadnim, saj ima dva starša namesto enega.
Ko se dela združevalni zapis, bo Git avtomatsko preračunal in združil vse različne
spremembe iz obeh vej. Če bo opazil, da so v obeh vejah na istem delu bile narejene
spremembe, tega ne bo mogel narediti in bo potrebna intervencija s strani uporabnika.
Takšnemu primeru pravimo združevalni konflikt (merge conflict).
7.6 Razreševanje konfliktov
Če sta obe veji, ki ju želimo združiti, spremenili isti del iste datoteke, Git ne bo mogel
ugotoviti, katero različico je treba uporabiti. Ko pride do take situacije, se ustavi tik
preden naredi zapis, tako da lahko konflikte rešimo ročno. Ukaz git status prikaže,
katere datoteke je treba razrešiti.
Na primer imamo master in conflict-test veji in v obeh spremenimo drugo vrstico
datoteke file-3.txt. Ob zagonu git merge ukaza bi videli nekaj podobnega:
master
feature
skupno izhodišče
združevalni zapis
31
$ git checkout master $ git merge conflict-test Auto-merging file-3.txt CONFLICT (content): Merge conflict in file-3.txt Automatic merge failed; fix conflicts and then commit the result.
Git ob konfliktu uredi vsebino prizadetih datotek s kazalniki, ki označujejo obe strani
sporne vsebine. Ti kazalniki so: <<<<<<<, ======= in >>>>>>>. Vsebina pred oznako
======= je od prejemne veje (v našem primeru master) in del, ki sledi, je od veje, ki jo
združujemo (v našem primeru conflict-test).
Primer takšne vsebine zgleda takole:
This is some nice text <<<<<<< HEAD This is some nice text in the second line EDIT ON MASTER ======= This is some nice text in the second line EDIT ON CONFLICT TEST >>>>>>> conflict-test This is some nice text in the third line
Ko odpravimo vse konflikte v datotekah, moramo Gitu to sporočiti z ukazom git add.
Sedaj lahko zaženemo git commit, da ustvarimo združevalni zapis.
Združevalni konflikti se lahko pojavijo samo pri three-way združevanju vej.
32
8 SODELOVANJE
Kot že omenjeno, je Git distribuiran sistem za verzioniranje kode. To pomeni, da lahko
lokalno skladišče zapisov in vej delimo z drugimi ljudmi. S tem omogočimo, da lahko tudi
ostali prispevajo v skladišče in dodajajo svoje zapise ter veje (slika 8.1).
Slika 8.1: Izmenjava podatkov med lokalnim in oddaljenim skladiščem
V naslednjih podpoglavjih bomo videli, kako s pomočjo ukazov git remote,
git fetch, git push in git pull urejamo povezave do oddaljenih skladišč ter
sinhroniziramo spremembe zapisov in vej. Za predstavitev teh ukazov bomo delali na
primeru uporabe GitHub storitve za gostovanje Git skladišč.
33
8.1 Git remote
Ukaz git remote nam omogoča dodajanje, pregledovanje in odstranjevanje povezav
do oddaljenih skladišč. Oddaljene povezave nam omogočijo, da se lahko na oddaljena
skladišča sklicujemo s krajšimi imeni namesto celotnega URL naslova. Poleg tega imamo
tudi priročen nabor vseh imen, katera uporabimo kot argument v Git ukazih.
Za začetek najprej dodajmo oddaljeno povezavo v naše lokalno skladišče z ukazom
git remote add <ime> <url>. Ta ukaz rabi dva argumenta, in sicer ime oddaljene
povezave ter URL, kjer se oddaljeno skladišče nahaja.
$ git remote add ghub https://github.com/ronzyfonzy/hobby-project.git
Če sedaj poženemo ukaz git remote, nam izpis vrne kratko ime ghub za povezavo do
GitHub skladišča. Če dodamo zastavico -v, nam vrne tudi ustrezen URL naslov.
$ git remote ghub $ git remote -v ghub https://github.com/ronzyfonzy/hobby-project.git (fetch) ghub https://github.com/ronzyfonzy/hobby-project.git (push)
Ko poženemo ukaz git clone nam Git avtomatsko doda povezavo z imenom origin, ki
se sklicuje na URL oddaljenega skladišča.
Dodatni podukazi, ki nam jih git remote ponuja, so preimenovanje
$ git remote rename ghub ghub2
ter brisanje.
$ git remote rm ghub
34
Ko imamo dodane povezave v lokalnem skladišču, lahko začnemo s sinhronizacijo vej in
zapisov.
8.2 Git push
Ukaz git push nam omogoča, da prenašamo veje z njenimi zapisi iz lokalnega v
oddaljeno skladišče. Ukazu lahko nakažemo, v katero oddaljeno skladišče želimo
prenesti katero vejo z naslednjo stukturo: git push <povezava> <veja>.
Če želimo prenesti master vejo na našo dodano ghub povezavo, zaženemo naslednji
ukaz:
$ git push ghub master Enumerating objects: 36, done. Counting objects: 100% (36/36), done. Compressing objects: 100% (32/32), done. Writing objects: 100% (36/36), 3.19 KiB | 1.59 MiB/s, done. Total 36 (delta 15), reused 0 (delta 0) remote: Resolving deltas: 100% (15/15), done. To https://github.com/ronzyfonzy/hobby-project.git * [new branch] master -> master
Po izvedbi ukaza smo uspešno prenesli vse lokalne zapise iz master veje (vključno z vejo)
v GitHub oddaljeno skladišče. Sedaj lahko tudi ostali ljudje, ki imajo dostop do tega
skladišča, dodajajo veje in zapise.
8.3 Git fetch
Osebe lahko dodajajo zapise in veje na oddaljeno skladišče. Te zapise in veje lahko
lokalno preglejujemo tudi mi. Ukaz git fetch prenaša zapise, datoteke in reference v
lokalno skladišče, brez da bi te spremembe združili. Na ta način lahko preverimo, kaj je
bilo sprememnjeno v oddaljenem skladišču, preden te spremembe združimo v lokalno
skladišče.
35
Predpostavljajmo, da je nekdo na master veji naredil spremembo v datoteki file-3.txt in
to prenesel na oddaljeno skladišče. Če poženemo ukaz git fetch, bi izpis zgledal
nekako takole:
$ git fetch ghub master remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From https://github.com/ronzyfonzy/hobby-project * branch master -> FETCH_HEAD 1e866d1..fe17899 master -> ghub/master
Iz izpisa lahko razberemo, da naša lokalna master veja ne vsebuje vseh sprememb, ki so
na oddaljenem ghub skladišču. Da dobimo informacijo, kateri zapisi nam manjkajo,
lahko lokano poženemo naslednjo kombinacijo git log ukaza:
$ git log --oneline master..ghub/master fe17899 (ghub/master) Updated file 3
Vidimo, da je razlika med našo lokalno master vejo ter oddaljeno ghub/master vejo v
enem zapisu fe17899.
Za združitev teh sprememb lahko uporabimo git merge ukaz, ki bo z fast-forward
združevalno strategijo združil spremembe v našo aktivno vejo. Najprej se prepričamo,
da smo na pravi aktivni veji z ukazom git branch in nato poženemo ukaz za
združevanje.
$ git merge ghub/master Updating 1e866d1..fe17899 Fast-forward file-3.txt | 1 + 1 file changed, 1 insertion(+)
36
Sedaj smo uspešno združili spremembe v lokalno skladišče. Kasneje bomo ugotovili, da
je git fetch varna alternativa git pull ukazu.
8.4 Git pull
Podobno kot git fetch nam ukaz git pull prenese datoteke iz oddaljenega
skladišča. Razlika je v tem, da prenešeno vsebino takoj združi v lokalno skladišče.
Dejansko je git pull ukaz kombinacija git fetch in git merge ukazov.
Na podlagi primera iz prejšnjega poglavja bomo sedaj uporabili ukaz git pull, da
združimo spremembe iz oddaljenega skladišča.
$ git pull ghub master From https://github.com/ronzyfonzy/hobby-project * branch master -> FETCH_HEAD Updating 1e866d1..fe17899 Fast-forward file-3.txt | 1 + 1 file changed, 1 insertion(+)
37
9 POTEKI DELA
Dokler na projektu delamo sami, ni večjega problema. Ampak če se sčasoma pridruži več
ljudi, je potrebno delo organizirati in razdeliti. Če še poleg tega vključimo, da morajo
razvijalci svoje delo odlagati v centralno Git skladišče, lahko hitro izgubimo rdečo nit,
katere veje in zapisi so bili namenjeni za kaj (slika 9.1). Glede na to kako je Git fleksibilen,
ni nobenega standarda, ki bi zapovedoval, kako ga je potrebno uporabljati. Za ta namen
imamo različne pristope, kako organizirati uporabo Gita s poteki dela. Poteki dela so
priporočilo, kako uporabljati Git, da je delo dosledno, strukturirano in produktivno.
Poleg tega vzpodbuja uporabnika, da efektivno in konsistentno uporablja Git.
Pomembno je, da se celotna ekipa, ki dela na projektu z Git verzioniranjem izvorne kode,
strinja z zastavljenim potekom dela.
Slika 9.1: Primer neorganiziranega vejanja Git skladišča
Vir: http://i.imgur.com/LpXVPxv.png [15.08.2019]
Poznamo kar nekaj potekov dela za Git in je zato izbira, kateri je pravi, odvisna od
različnih faktorjev (velikost ekipe, skaliranje projekta in ekipe, težavnost razveljavljanja
38
sprememb ...). Nekaj najbolj pogostih potekov dela bomo opisali v naslednjih
podpoglavjih.
9.1 Centraliziran potek dela
Pri centraliziranem poteku dela ekipa uporablja eno centralno oddaljeno skladišče, svoja
lokalna skladišča ter eno vejo razvoja (ponavadi z imenom master). Vsak razvijalec mora
pred pošiljanjem svojih sprememb v oddaljeno skladišče poskrbeti, da so vse
spremembe oddaljenega skladišča prisotne lokalno. Če te spremembe niso lokalno
prisotne, jih mora prenesti s pomočjo ukaza git pull in zastavice --rabase.
$ git pull --rebase ghub master
V primeru da imamo konflikte, le-te odpravimo in shranimo popravke. Zatem lahko
pošljemo spremembe v oddaljeno skladišče s pomočjo ukaza git push.
9.2 Funkcionalni potek dela
Funkcionalni potek dela je razširitev centralnega poteka dela. Glavni koncept pri tem
poteku dela je vejanje. Vsaka nova funkcionalnost ali dograditev k projektu mora
potekati v svoji veji namesto na glavni master veji. Na ta način lahko več razvijalcev dela
na posamezni funkcionalnosti, ne da bi spreminjali glavno vejo. To pomeni tudi, da
glavna veja ne sme nikoli vsebovati nedelujoče kode, kar je velika prednost za okolja z
nenehno integracijo.
9.3 Potek dela Gitflow
Januarja 2010 je Vincent Driessen objavil svoj potek dela, ki ga je uporabljal tako
privatno kot pri svojem delu. Gitflow definira striktno vejanje okoli verzij projekta in je
zato najbolj primeren potek dela, kjer imajo projekti načrtovan cikel izdaj verzij. Ne uvaja
nobenih novih konceptov, kot jih funkcionalni potek dela, marveč dodeljuje specifične
vloge določenim vejam ter kako in kdaj je potrebno s temi vejami delati.
39
Slika 9.2: Primer Gitflow poteka dela
Gitflowov potek dela se sestoji iz glavnih in podpornih vej. Podporne veje se naprej delijo
na funkcionalne veje, veje za verzije ter popravljalne veje vej (slika 9.2). V naslednjih
podpoglavjih bomo na kratko opisali pomen in življenjski cikel teh vej.
9.3.1 Glavni veji
V Gitflowovem poteku dela imamo dve glavni veji, in sicer master ter develop, ki imata
neskončen življenjski cikel. Praviloma je tako, da master veja vsebuje kodo, ki je vedno
pripravljena za produkcijo, medtem ko develop odraža najnovejše spremembe pred
novo objavo verzije.
9.3.2 Funkcionalne veje
Funkcionalne veje se lahko razvejajo iz develop veje in se morajo na koncu združiti nazaj.
Namenjene so razvoju novih funkcionalnosti, ki bodo vključene v projekt v bližnji ali
daljnji prihodnosti. Življenski cikel teh vej je tako dolg, dokler funkcionanost ni
hotfix
master
release
develop
feature
feature
v0.1 v0.2 v0.3
40
zaključena ali zavržena. Konvencija imen funcionalnih vej je lahko karkoli razen master,
develop, release-* ali hotfix-*. Za boljši pregled jih poimenujemo tudi feature/*.
9.3.3 Veje za verzije
Veje za verzije se razvejajo iz develop veje in se združijo v develop in master. Začetek
takšne veje je ponavadi, ko develop veja doseže željeno raven funkcionalnosti in
stabilnosti za naslednjo verzijo. Namenjene so pripravi nove različice projekta (priprava
meta podatkov, številke verzije, ipd.). Ko so vse priprave dokončane, zaključimo vejo v
master in develop ter dodamo oznako na master vejo s številko verzije. Konvencija imen
vej za verzije release-* ali release/*.
9.3.4 Popravljalne veje
Popravljalne veje se razvejajo iz master, združijo pa se v master in develop. Podobne so
vejam za različice vendar niso načrtovane. Kreirajo se, ko je potrebno na
produkcijski/master kodi nemudoma narediti popravek. Ko je popravek implementiran,
se ponovno naredijo priprave za novo različico (priprava meta podatkov, številke verzije,
ipd.) in veja se zaključi. Tudi v tej situaciji se naredi oznaka na master vejo z novo številko
verzije.
9.4 Upravljalski potek dela
Pri prejšnjih potekih dela je odlagališče dela centralno skladišče. Poznamo pa tudi
uporavljalski potek dela, kjer ima vsak razvijalec poleg lokalne kopije tudi svoje
oddaljeno skladišče, kamor oddajajo svoje delo. Ko v razvijalsko oddaljeno skladišče
oddajo spremembe, pride na vrsto upravitelj glavnega skladišča, kamor združi delo iz
skladišč razvijalcev.
41
Slika 9.3: Prikaz upravljalskega poteka dela
Takšen potek dela dostikrat vidimo pri odprtokodnih projektih, ki so na primer na
storitve GitHub (slika 9.3). Predpostavljajmo, da smo naredili program in ga verzionirali
lokalno z Git sistemom. Sedaj želimo projekt deliti tudi z drugimi in smo se odločili, da
ga prenesemo na oddaljeno skladišče v storitev GitHub. Če nastavimo, da je projekt
javen, lahko katerikoli uporabnik storitve GitHub naredi tako imenovani fork oziroma
odcepitev našega projekta. Ob tej akciji se drugemu uporabiku naredi klon projekta v
njegov račun. Podobno kot da bi projekt klonirali na svoj računalnik, le da je kloniran
oddaljeno. Sedaj lahko drug uporabnik nadaljuje razvoj, kot se njemu zdi primeren, in
dodaja popravke ali nove funkcionalnosti. Če želi pa nas lahko s pomočjo določenih
mehanizmov na storitvi obvesti, da te popravke ali funkcionalnosti vključimo v svoj
originalni projekt.
42
10 DISTRIBUIRANOST
Ena izmed glavnih prednosti Git sistema za verzioniranje kode je distribuiranost. Tudi če
uporabljamo centraliziran potek dela, ima vsak uporabnik lokalno kopijo skladišča. V
primeru izgube oddaljenega centralnega skladišča lahko kdorkoli ponovno postavi novo
skladišče s pomočjo lokalne kopije. Posledično Git nima ene točke odpovedi (single point
of failure), razen če imamo samo eno kopijo skladišča. Vizualni primer takšne
distribuiranosti vidimo na sliki 10.1.
Slika 10.1: Primer distribuiranega skladišča s tremi razvijalci
Za primerjavo si poglejmo Subversion - eden izmed prednikov Gita. Subversion je imel
samo eno oddaljeno centralno skladišče. Se pravi, da sta vsak nov zapis in veja morala
direktno na to skladišče (brez predhodnega zapisa lokalno). Ta način dela je sčasoma
privedel do številnih problemov.
Eden izmed glavnih problemov so bili združevalni konflikti. S tem je prihajalo do motenj
pri delu, saj je morala ekipa konflikt rešiti, če so hoteli nadaljevati delo. Vsekakor
združevalni konflikti obstajajo tudi v Git sistemu, ampak ne ovirajo dela in jih je dosti
Centralno skladišče
Razvijalec #1 git pull
git push
urejevalnik
Razvijalec #2git pull
git push
urejevalnik
Razvijalec #3
git pullgit push
urejevalnik
43
lažje in hitreje razrešiti. Drug večji problem je bila ena točka odpovedi. Če se je skladišče
nekako pokvarilo, so morali vsi počakati, da se je skladišče obnovilo iz varnostne kopije,
ki se je morala izvajati neodvisno.
Oddaljena skladišča so tako ključen del odlaganja zapisov ter sodelovanja. Obstajajo hitri
načini, kako omogočiti dostop do Git skladišča, ki ga imamo na lastnem računalniku. Ta
način ni najbolj priročen, ker moramo zagotoviti, da računalnik vedno dela. Če ne dela,
potem drugi razvijalci nimajo dostopa do skladišča. Za rešitve se obrnemo na storitve za
gostovanje Git skladišč. Storitve nam ponujajo, da je lahko naše skladišče javno (vsakdo
si lahko ogleduje kodo in dodaja spremembe do določene mere) ali privatno (dostop
imajo samo ljudje, katere predhodno povabimo v projekt).
Trenutno imamo na voljo kar nekaj storitev za gostovanje Git skladišč. V glavnem
ponujajo isto osnovo, ampak se najbolj razlikujejo po ceni ter dodatnih storitvah,
integracijah in orodjih okoli njih. Ne glede na to se je potrebno odločiti, kam bomo
odlagali svojo kodo. In to ni vedno lahka odločitev. Potrebno se je zavedati, da bomo
zaupali svojo intelektualno lastnino ali intelektualno lastnino podjetja drugemo
podjetju. To podjetje bo našo kodo obdelovalo in shranjevalo na svoje strežnike preko
programov, ki so jih pisali ljudje. In ta celotna infrastruktura ter programi, ki pri tem
sodelujejo, je bila postavljena in sprogramirana s pomočjo ljudi, ki delajo napake. Zaradi
teh napak obstaja potencialna verjetnost, da bodo zlonamerni ljudje vdrli v storitev in si
pridobili našo kodo. Storitve, ki jih bom zelo na kratko opisal v naslednjih podpoglavjih,
so precej znane in podprte s strani velikih podjetij, ki že vrsto let delajo in izboljšujejo
tako uporabniško izkušnjo kot varnost samo. Vendar pa še vedno tu ali tam pride do
kakšnega incidenta.
44
10.1 SourceForge
SourceForge, ki ga je leta 1999 ustanovilo podjetje VA Software, je bil prvi ponudnik
centralizirane lokacije za brezplačne in odprtokodne programe. Logotip storitve je
prikazan na sliki 10.2.
Slika 10.2: Logotip storitve za gostovanje Git skladišč Source Forge.
Vir: https://en.wikipedia.org/wiki/SourceForge#/media/File:Sourceforge_logo.png [4.8.2019]
Uporabniki imajo dostop do orodij za upravljanje projektov in centraliziranega
pomnilnika, kamor so lahko odlagali datoteke, preko katerih so ostali uporabniki dobili
dostop do programov. Najbolj pa je znan po ponudbi sistemov za verzioniranje kode, kot
so CVS, SVN, Mercurial in navsezadnje tudi Git.
Pred leti je bilo to središče za odprtokodne programe, vendar so sčasoma uporabniki
začeli izgubljati zaupanje v storitev. Dostikrat se je zgodilo, da je bila stran nedostopna
po več ur in ni bilo nobenega poročanja, zakaj se je to zgodilo ter kdaj mislijo napako
odpraviti. Zaradi takšnih netransparentnih dogodkov so uporabniki prehajali na nove in
bolj stabilne storitve, kot je naprimer GitHub.
10.2 Bitbucket
Bitbucket je bilo na začetku neodvisno zagonsko podjetje, ki ga je ustanovil Jesper Nøhr.
Septembra 2010 je Atlassian (avstralsko podjetje programskih storitev) kupil Bitbucket
in je ponujal gostovanje samo za Mercurial projekte. 3. oktobra 2011 je Bitbucket uradno
oznanil podporo za gostovanje Git skladišč. Logotip storitve je prikazan na sliki 10.3.
45
Slika 10.3: Logotip storitve za gostovanje Git skladišč Bitbucket.
Vir: https://en.wikipedia.org/wiki/Bitbucket#/media/File:BitBucket_SVG_Logo.svg [4.8.2019]
Bitbucket ponuja tako komercialne kot tudi brezplačne pakete. Bil je eden izmed prvih,
ki je ponujal brezplačni paket z neomejenim številom zasebnih skladišč. Je precej
priljubljena storitev za gostovanje Git skladišč predvsem zaradi integracije z drugimi
Atlassian storitvami, kot so Jira, HipChat ali Confluence. Če želimo imeti v podjetju
celoten delovni proces sklenjen (planiranje, dokumentacija, razvoj, podpora,
sodelovanje in mnogo več), ima Atlassian precej dobro podlago s svojimi storitvami.
Aprila 2019 je Atlassian sporočil, da je Bitbucket dosegel 10 milijonov registriranih
uporabnikov in več kot 28 milijonov skladišč.
Bitbucket ima različne modele gostovanja. Naše skladišče lahko gostuje na njihovih
strežnikih (Cloud model) ali pa si postavimo njihovo storitev na lastnem strežniku (Self-
hosted model), vendar pri tem izgubimo nekaj prednosti, ki jih ponuja prvi model.
10.3 GitLab
Dmitriy Zaporozhets in Valery Sizov sta leta 2011 začela s projektom, ki bi za razvijalce
zagotavljal efektivno in prijetno orodje, s katerim se lahko osredotočiš na delo, namesto
na nastavljanje drugih orodij. Razvila sta spletno orodje GitLab, ki ga sedaj naprej razvija
podjetje GitLab Inc. Zagotavlja upravljanje Git skladišč ter dodatne funkcionalnosti, kot
so središče za dokumentacijo, sledenje problemov, planiranje projekta, integracijo in še
več. Uporablja ga več velikih tehnoloških podjetij, vključno z IBM, Sony, NASA, Alibaba,
Oracle, O'Reilly Media, CERN, GNOME, Boeing in SpaceX. Logotip storitve je prikazan na
sliki 10.4.
46
Slika 10.4: Logotip storitve za gostovanje Git skladišč GitLab.
Vir: https://en.wikipedia.org/wiki/GitLab#/media/File:GitLab_logo.svg [4.8.2019]
GitLab ponuja tako gostovanje na njihovih strežnikih kot tudi postavitev storitve na
lastnem strežniku. Obe varianti ponujata brezplačen paket, ki pa je omejen s
fukncionalostmi. Ne glede na omejitev dobimo v brezplačnem paketu vse, kar rabimo,
da lahko začnemo projekt manjšega ali srednjega razreda.
10.4 GitHub
Februarja 2018 je GitHub zaživel s pomočjo Chrisa Wanstratha, P. J. Hyetta, Toma
Prestona-Wernerja in Scotta Chacona, pod okriljem podjetja GitHub Inc., ustanovljenega
leta 2007. Leta 2018 pa ga je kupilo podjetje Microsoft. Je ena izmed najbolj priljubljenih
storitev med odprtokodnimi projekti sodeč po poročilu iz maja 2019. V poročilu je bilo
zapisano, da imajo 37 milijonov uporabikov ter več kot 100 milijonov skladišč (28
milijonov od teh je javnih).
Slika 10.5: Logotip storitve za gostovanje Git skladišč GitHub.
Vir: https://en.wikipedia.org/wiki/GitHub#/media/File:GitHub_logo_2013_padded.svg [4.8.2019]
Tako kot ostale storitve tudi GitHub poleg skladišč ponuja orodja za dokumentacijo,
sledenje problemov, planiranje projekta, integracijo in še več. Predvsem je zanimiv graf,
ki prikazuje aktivnost uporabnika in koliko je prispeval k projektom.
47
Slika 10.6: Primer aktivnosti uporabnika za storitve GitHub. Vsak kvadratek predstavlja dan in bolj je
zelen bolj je bil bil uporabnik aktiven oz. več je prispeval k projektom.
Vir: https://help.github.com/assets/images/help/profile/contributions_graph.png [4.8.2019]
Preden je leta 2018 Microsoft prevzel GitHub ni bilo brezplačnega paketa, kjer bi lahko
skladiščil privatne projekte. Od prevzema naprej pa GitHub ponuja neomejeno število
javnih kot tudi privatnih projektov.
48
11 GRAFIČNI VMESNIKI
Kot že rečeno, je za nekatere upraba terminala težka. Še posebej za uporabnike, ki so
večino časa uporabljali programe z grafičnimi vmesniki. Za lažjo tranzicijo in uporabo Git
sistema za verzioniranje kode se je tekom let razvilo število programov z grafičnimi
vmesniki, ki izkoriščajo Git ukaze in vse skupaj prikažejo na način, ki je dostopen večjemu
spektru ljudi. Tudi jaz sem na zažetku imel težave in so mi ti grafični vmesniki sprva
pomagali pri osnovnih operacijah, kasneje pa sem se znašel v situacijah, ko sem rabil
določene funkcionalnosti, ki jih grafični vmesnik ni imel. Takrat sem z dosti večjo
samozavestjo odprl terminal in začel izvajati Git ukaze.
V osnovi imajo vsi programi prikazovalnik vej in zapisov, podobno kot ga dobimo, če
poženemo ukaz git log --graph. Nadgradnja teh prikazovalnikov je interaktivna
uporaba in manipulacija skladišča, vej in zapisov brez uporabe terminala. Na ta način
lahko zelo hitro dosežemo iste rezultate, kot če bi uporabljali terminalne ukaze.
Vsekakor pa ti programi ne nadomestijo vseh funkcionalnosti in moči, ki jih lahko
pridobimo samo preko terminalnih ukazov Git sistema.
Tekom let sem uporabljal marsikateri program in nikoli nisem bil zadovoljen z nobenim.
Vse dokler nisem odkril GitKraken. Podjetje Axosoft je prvo stabilno različico programa
objavilo leta 2016 in od takrat naprej ga spremljam in uporabljam z največjim
zadovoljstvom. Preden pa se spustimo v ta program, pa v sledečih podpoglavjih
poglejmo nekaj ostalih grafičnih vmesnikov za Git.
11.1 SmartGit
Prvi grafični vmesnik za Git, katerega sem uporabljal, je bil SmartGit podjetja Syntevo.
Leta 2009 so objavili prvo različico, ki je vsebovala le osnovne funkcionalnosti. Skozi leta
pa so program kar dodobra izpopolnjevali. Ker sem dostikrat delal v različnih
operacijskih sistemih (Windows, Linux, macOS), je bil program idealen, saj je delal na
vseh omenjenih sistemih. Vendar sem se venomer znašel v situacijah, ko program ni
49
naredil, kar bi moral. Prihajalo je do tega, da mi je za določene akcije pokvaril Git delovno
okolje in sem moral reševati problem v terminalu (zahvajlujoč tem problemom sem se
sploh lotil uporabe Git v terminalu). Tudi sam grafični vmesnik je bil bolj skop ampak so
ga dopolnili leta 2013, ko so objavili četrto različico. V veliko pomoč je bila tudi nova
vgrajena funkcionalnost za razreševanje združevalnih konfliktov, ki so mi na začetku
uporabe Gita delali največ problemov.
Vendar me ta prenova in dodatne
fukcionalnosti niso odvrnili od tega,
da ne bi vseskozi iskal neko
alternativo. Omeniti je potrebno tudi,
da lahko program uporabljaš
brezplačno za odprtokodne oziroma
nekomercionalne projekte. To je
predstavljalo manjši problem, ker sem
želel, da bi ga lahko uporabljali vsi v
podjetju, ampak je bila cena trakrat še
malce nedostopna.
11.2 SourceTree
Moja alternativa programu SmartGit je SourceTree. Izdelal ga je Steve Streeting, a je leta
2011 dal pod okrilje podjetja Atlassian. Izredno intiutiven program, za katerega je bila
leta 2010 izdana prva različica, ki je delala samo na macOS operacijskem sistemu. Tri leta
zatem je z različico 1.5 prišla podpora tudi za Windows.
Slika 11.1: Izgled novejše različice programa SmartGit.
Vir:
https://www.syntevo.com/assets/images/products/smartgit/
opener-481720cb.png [4.8.2019]
50
Slika 11.2: Izgled programa SourceTree (različica 1.5).
Vir: https://blog.sourcetreeapp.com/2016/03/01/sourcetree-design-whats-next [4.8.2019]
Najbolj praktični deli tega programa so bili hitrost, vgrajen urejevalnik za razreševanje
združevalnih konfliktov ter vgrajena funkcionalnost za upravljanje skladišča po Gitflow
poteku dela. Zaradi slednje vgrajene funkcionalnosti sem hitro opazil prednosti uporabe
tega poteka dela. Predvsem pri tem, da smo znotraj razvijalske ekipe imeli čedalje manj
združevalnih konfliktov. Vendar nisem bil popolnoma zadovoljen s programom in tako
se je nadaljevalo iskanje alternative.
11.3 GitKraken
Navsezadnje pridemo do programa GitKraken podjetja Axosoft. Kot omenjeno, je bil
prvič objavljen leta 2016 in prva različica je bila zelo skromna v smislu funkcionalnosti.
Ampak mene osebno je najbolj pritegnil vizualni izgled programa ter vizualizacija vej,
zapisov in funcionalne interakcije med njimi. Po mojem je bil in je še vedno to paradni
51
konj programa GitKraken. Sedaj leta 2019 je izšla različica 6.0 (slika 11.3), ki je prinesla
izredno pohitritev programa ter možnost dela nad več skladišči naenkrat.
Slika 11.3: Izgled različice 6.0.1 programa GitKraken
Poleg osnovnih funckionalnosti prinaša integracijo z večjimi storitvami gostovanja Git
skladišč, integriran razreševalnik združevalnih konfliktov, upravljalec Git profilov,
urejevalnik interaktivne rebase Git funkcije ter mnogo več. Poleg tega ima vgrajen tudi
podprogram za planiranje in sledenje projekta imenovan GloBoard.
52
12 IZKUŠNJE S TERENA
Tekom let se je moj osebni način uporabe Git sistema precej spremenil. Na začetku, ko
sem bolj ali manj sam delal na projektu, sem uporabo sistema za verzioniranje kode
smatral bolj kot dodatno delo kot nekaj, kar bi pripomoglo k razvoju. Ena stvar, ki sem
se je kmalu zatem naučil, je bilo pomanjkanje sledljivosti sprememb. En dan sem delal
na abstrakciji ene funkcije in sem naslednji dan ugotovil, da sem se je lotil iz napačnega
zornega kota. Na svojo žalost nisem imel več vpogleda, kako je bila funkcija prvotno
implementirana. Spet drugič se mi je zgodil primer, ko sem skoraj izgubil celoten projekt,
ker ga nisem imel nikjer drugje kot na svojem lokalnem disku prenosnika. Zaradi takšnih
situacij sem se zatekal k drugačnim rešitevam, kot je uporaba storitev Dropbox, ki
datoteke kopirajo v oddaljen strežnik ob vsaki spremembi. Ampak to se mi je zdela
precej grda rešitev, vendar je bilo bolje kot nič.
Stvari so se pa še bolj zapletle, ko smo s tremi prijatelji (Davor, Tadej in David) začeli
delati na skupnem projektu z imenom Weatherlove - android aplikacija za prikazovnje
vremenske napovedi z izjemno lepimi gradniki. Na začetku smo se celo dogovarjali, kdo
bo delal na katerem delu projekta, da si nismo prepisovali kode. Vendar smo kaj kmalu
začeli uporabljati Git v povezavi z Bitbucket storitvijo, kjer smo imeli centralno skladišče.
53
Slika 12.1: Primer vejanja in zapisov na začetku projekta Weatherlove
Delo s projektom smo si precej olajšali, ampak smo še vedno naleteli na zaplete in
ogromno združevalnih konfliktov, ki si jih v določenih primerih nismo znali razlagati. Tudi
sporočila, ki smo jih dodajali zapisom, niso kaj veliko pripomogla k razreševanju teh
konfliktov (slika 12.1). Vse to je bila bolj ali manj posledica pomanjkanja strukture in
internih pravil, kako se naj upravlja in dela s skladiščem. Na začetku nismo uporabljali
nobenih pravil in standardov in je bil Git način, kako spraviti kodo iz računalnika enega
razvijalca do drugega, brez da bi pokvarili kodo. Sčasoma smo na novejših projektih
uvedli Gitflow potek dela, ki je drastično izboljšal način in abstrakcijo dela ter sledljivost,
kdaj se je kaj delalo oziroma kaj je še v delu (slika 12.2).
54
Slika 12.2: Izgled vej in zapisov po uvedbi standardov sporočil in GitFlow poteku dela
Pri vsem tem procesu sem jaz osebno imel največji problem z uporabo terminala (na
začetku sem bil zelo nevešč uporabnik) ter z razumevanjem, kako vso to vejanje poteka.
Sem zelo vizualna oseba in stvari lažje razumem, če si jih znam orisati ali predstavljati.
Tu so predvsem prišli v pomoč grafični vmesniki, ki so Git skladišču dodali to, kar mi je
vedno manjkalo – vizualne indikatorje ter interakcijo s skladiščem brez uporabe
terminala. Na podlagi tega sem se naučil, kako lahko te vizualne interakcije prenesem v
terminal in izkoristim dodatne funkcionalnosti, ki jih grafični vmesniki niso mogli.
55
13 SKLEP
Dandanes je ključnega pomena, da so podjetja, ki se ukvarjajo s programskimi produkti,
hitra, učinkovita in kakovostna. To lahko dosežemo na različne načine, bodisi s
povečanjem delovne sile ali dodajanjem delovnih procesov, ki prispevajo k tem
atributom. Vendar dodajanje več in več kompleksnosti v podjetje ali v produkt lahko
privede do ravno obratnega učinka.
Na podlagi svojih izkušenj v podjetju sem šel skozi takšen proces, kjer smo zaradi
povečanja dela izbrali pristop dodajanja kompleksnosti v obliki delovne sile. Vendar smo
skozi čas in s preizkušanjem različnih pristopov prišli do tega, da je bilo potrebno
spremeniti samo delovni proces. Naredili smo abstrakcijo določenih življenjskih ciklov
razvoja produkta ter določene dele avtomatizirali. S tem smo dosegli dosti večjo hitrost
in kvaliteto produkta ter povečali učinkovitost manjše ekipe. Git je bil pri tem ključnega
pomena, saj je stičišče med razvojem, vodenjem projekta, zagotavljanjem kvalitete
produkta in avtomatizacijo procesov.
Ne glede na vse to je Git postal izjemno popularen zaradi sledečih razlogov:
- Distribuiran pristop: Git omogoča, da lahko spremembe zapisujemo lokalno in
imamo s tem kontrolo nad celotno izvorno kodo projekta.
- Svoboda: Git ne omejujejo zakonodaje, kako ga je potrebno uporabljati. Tako
lahko posamezniki, ekipe in podjetja prilagodijo delovne procese in upravljanja s
skladiščem po svojih zahtevah.
- GitHub je storitev, ki je nadomestila SourceForge v odportokodnem ekosistemu.
GitHub je postal mesto, kjer se najdejo in objavljajo odprtokodni projekti. Že od
samega začetka so izbrali Git za sistem verzioniranja.
Dandanes si razvoja programskih rešitev ne predstavljamo brez kakršnega koli sistema
za verzioniranje kode. Ampak mogoče z leti to ne bo več potrebno, mogoče bodo
programi verzionirali sami sebe.
56
VIRI IN LITERATURA
Attlasian, Bitbucket. Getting Git right, What is verison control. Dostop na:
https://www.atlassian.com/git/tutorials/what-is-version-control [16. 5. 2019]
Attlasian, Bitbucket. Getting Git right, Source code management. Dostop na:
https://www.atlassian.com/git/tutorials/source-code-management [17. 5. 2019]
Eric Sink. Version Control by Example. Dostop na:
https://ericsink.com/vcbe/html/reading_this_book.html [13. 5. 2019]
IBM Developer. Learn the workings of Git, not just the commands. Dostop na:
https://developer.ibm.com/tutorials/d-learn-workings-git/ [20. 7. 2019]
Vincent Driessen. A successful Git branching model. Dostop na:
https://nvie.com/posts/a-successful-git-branching-model/ [8. 7. 2019]
Oliver Steele. My Git Workflow. Dostop na:
https://blog.osteele.com/2008/05/my-git-workflow/ [8. 7. 2019]
Git community. Git --distributed-is-the-new-centralized. Dostop na:
https://git-scm.com/about/distributed [31. 7. 2019]
Michael Hampton. Why does everyone use Git in a centralized manner? Dostop na:
https://softwareengineering.stackexchange.com/a/315276/160658 [3. 8. 2019]
Wikipedia. Bitbucket. Dostop na:
https://en.wikipedia.org/wiki/Bitbucket [3. 8. 2019]
57
Wikipedia. SourceForge. Dostop na:
https://en.wikipedia.org/wiki/SourceForge [4. 8. 2019]
Wikipedia. GitLab. Dostop na:
https://en.wikipedia.org/wiki/GitLab [4. 8. 2019]
syntevo. SmartGit – First Milestone. Dostop na:
https://www.syntevo.com/blog/?p=3482 [4. 8. 2019]