-
1. Početak
- 1.1 O kontroli verzije
- 1.2 Kratka istorija Gita
- 1.3 Osnove Gita
- 1.4 Komandna linija
- 1.5 Instaliranje Gita
- 1.6 Podešavanja za prvi put
- 1.7 Traženje pomoći
- 1.8 Rezime
-
2. Osnove Gita
- 2.1 Pravljenje Git repozitorijuma
- 2.2 Snimanje promena na repozitorijumu
- 2.3 Pregled istorije komitova
- 2.4 Opovrgavanje
- 2.5 Rad sa udaljenim repozitorijumima
- 2.6 Tagovanje
- 2.7 Alijasi
- 2.8 Rezime
-
3. Grananje u Gitu
- 3.1 Grananje ukratko
- 3.2 Osnove grananja i spajanja
- 3.3 Upravljanje granama
- 3.4 Tokovi rada sa grananjem
- 3.5 Udaljene grane
- 3.6 Rebaziranje
- 3.7 Rezime
-
4. Git on the Server
- 4.1 Protokoli
- 4.2 Postavljanje Gita na server
- 4.3 Generisanje javnog SSH ključa
- 4.4 Podešavanje servera
- 4.5 Git Daemon
- 4.6 Pametan HTTP
- 4.7 GitWeb
- 4.8 Opcije za hostovanje koje nude treća lica
- 4.9 Rezime
-
5. Distribuirani Git
- 5.1 Distribuirani tokovi rada
- 5.2 Kako doprineti projektu
- 5.3 Održavanje projekta
- 5.4 Rezime
-
6. GitHub
-
7. Git Tools
- 7.1 Revision Selection
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Advanced Merging
- 7.9 Rerere
- 7.10 Debugging with Git
- 7.11 Submodules
- 7.12 Bundling
- 7.13 Replace
- 7.14 Credential Storage
- 7.15 Summary
-
8. Prilagođavanje Gita
- 8.1 Konfiguracija Gita
- 8.2 Git atributi
- 8.3 Git hukovi
- 8.4 Primer polise sprovedene od strane Gita
- 8.5 Rezime
-
9. Git i ostali sistemi
- 9.1 Git kao klijent
- 9.2 Migriranje na Git
- 9.3 Rezime
-
10. Git iznutra
- 10.1 Vodovod i porcelan
- 10.2 Git objekti
- 10.3 Git reference
- 10.4 Paketoteke
- 10.5 Refspek
- 10.6 Transfer Protocols
- 10.7 Maintenance and Data Recovery
- 10.8 Environment Variables
- 10.9 Summary
-
A1. Appendix A: Git in Other Environments
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Eclipse
- A1.4 Git in Bash
- A1.5 Git in Zsh
- A1.6 Git in Powershell
- A1.7 Summary
-
A2. Appendix B: Embedding Git in your Applications
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
-
A3. Appendix C: Git Commands
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
3.2 Grananje u Gitu - Osnove grananja i spajanja
Osnove grananja i spajanja
Hajde da prođemo kroz jednostavan primer grananja i spajanja sa tokom rada kakav se često javlja u realnom svetu. Pratićete ove instrukcije:
-
Radite na veb-sajtu.
-
Napravite granu za novu priču na kojoj radite.
-
Radite nešto na toj grani.
U ovom trenutku, dobijate poziv da postoji kritičan problem koji morate da rešite istog trenutka. Uradićete sledeće:
-
Prebacite se na granu za produkciju.
-
Napravite novu granu na kojoj ćete dodati kôd koji rešava problem.
-
Kada ga testirate, spojite granu sa rešenjem problema, i gurnete na server.
-
Vratite se nazad na priču na kojoj ste radili.
Osnove grananja
Prvo, pretpostavimo da radite na projektu na kome već imate nekoliko komitova.

Odlučili ste da ćete raditi na problemu #53
koji se nalazi na kom god sistemu za praćenje problema koristi vaša kompanija.
Da biste napravili granu i skočili na nju istovremeno, možete da pokrenete komandu git checkout
sa opcijom -b
:
$ git checkout -b iss53
Switched to a new branch "iss53"
Ovo je skraćenica za:
$ git branch iss53
$ git checkout iss53

Radite neke stvari na svom veb-sajtu i obavite neke komitove.
Dok radite to, grana iss53
se kreće napred, jer je ona čekautovana (odnosno, HEAD
pokazuje na nju).
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'

iss53
se pomerila napred u skladu s poslom koji ste obavili.Sada dobijate poziv da postoji problem sa vebsajtom, i morate odmah da ga popravite.
Sa Gitom, ne morate da rešavate problem zajedno sa iss53
promenama koje ste napravili, i ne morate da ulažete mnogo truda u to da povratite te promene pre nego što možete da krenete da radite na rešavanju novonastalog problema.
Sve što treba da uradite jeste da se prebacite na master
granu.
Ipak, pre nego što to uradite, obratite pažnju na to da vam, ako vaš radni direktorijum ima nekomitovane promene koje su u konfliktu sa granom koju čekautujete, Git neće dozvoliti da promenite granu.
Najbolje da radno stanje bude čisto kada pravite skok između grana.
Postoje načini da se ovo zaobiđe (naime, skrivanje i komitovanje ispravki) koje ćemo obraditi kasnije, u [git_stashing].
Zasad, pretpostavimo da ste komitovali sve promene, tako da možete da se vratite na master
granu:
$ git checkout master
Switched to branch 'master'
U ovom trenutku, radni direktorijum vašeg projketa izgleda isto onako kako je izgledao pre nego što se počeli da radite na problemu #53, i možete da se koncentrišete na hitni slučaj. Ovo je bitna stvar koju treba zapamtiti: kada menjate grane, Git resetuje radni direktorijum da izgleda onako kako je izgledao kada ste poslednji put komitovali na toj grani. Dodaje, briše i modifikuje fajlove automatski da bi se postarao da vaša radna kopija izgleda tačno onako kako je izgledala na grani kada ste uradili poslednji komit.
Sledeće, treba da rešite hitan problem. Napravićemo hotfix
granu na kojoj ćemo raditi dok to ne bude sređeno.
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)

hotfix
grana bazirana na master
-u.Možete da testirate ono što ste uradili, da budete sigurni da je problem rešen, i da spojite to nazad sa granom master
.
Ovo možete da uradite pomoću komande git merge
.
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
Primetićete izraz Fast-forward
(motanje unapred) koji se pojavio na izlazu prilikom spajanja.
Pošto se komit C4
na koji pokazuje grana hotfix
u koju ste se spojili nalazio direktno ispred od komita C2
na kom ste bili, Git jednostavno pomera pokazivač napred.
Da parafraziramo, kada probate da spojite jedan komit sa komitom do kog se može stići prateći istoriju prvog komita, Git pojednostavljuje stvari tako što samo pomeri pokazivač napred jer nema divergencije sa kojom bi se spajao — zato se ovo zove motanje unapred.
Promena se sada nalazi u snimku komita na koji pokazuje master
grana.

master
se premotao unapred do hotfix
Pošto je super-važan problem rešen, vreme je da se vratite na ono što ste radili pre nego što ste bili prekinuti.
Ipak, prvo ćete obrisati hotfix
granu, jer vam više nije potrebna — grana master
pokazuje na isto mesto.
Možete je obrisati pomoću opcije -d
uz komandu git branch
:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
Sada se vraćate na tiket #53 i nastavljate sa radom
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)

iss53
Ovde treba napomenuti da posao koji ste odradili u grani hotfix
nije sadržan u fajlovima na grani iss53
. Ako vam je on potreban, možete da spojite granu master
u granu iss53
pokretanjem komande git merge master
, ili možete da sačekate sa integrisanjem tih promena dok kasnije ne odlučite da povučete granu iss53
nazad u master
.
Osnove spajanja
Pretpostavimo da ste odlučili da je rad na problemu #53 gotov i da je kod spreman da se spoji sa master
granom.
Da biste uradili to, treba da pripojite granu iss53
grani master
, kao što ste ranije spojili hotfix
.
Sve što treba da uradite jeste da čekautujete granu u koju želite da se spojite i da onda pokrenete git merge
komandu:
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
Ovo izgleda malo drugačije od spajanja hotfix
od ranije.
U ovom slučaju, istorija je divergirala na nekoj ranijoj tački.
Pošto komit na grani na kojoj se nalazite nije direktan predak grane u koju se spajate, Git mora uradi neki posao.
U ovom slučaju, Git radi jednostavan trostruki spoj, koristeći dva snimka na koje pokazuju vrhovi grana i njihovog zajedničkog pretka.

Umesto da samo pomeri pokazivač na granu napred, Git pravi novi snimak koji je rezultat ovog trostrukog spoja i automatski pravi novi komit koji pokazuje na njega. Ovo se naziva spojni komit (merge commit), i poseban je jedino u tom smislu što ima više od jednog roditelja.

Vredi napomenuti da je Git taj koji odlučuje koji zajednički predak je najbolje iskoristiti kao bazu za spoj; ovo je drugačije od starijih alata kao što su CVS i Subversion (pre verzije 1.5), gde programer koji radi spoj mora sam da odgonetne koji čvor je najbolja baza. Ovo čini spajanje mnogo jednostavnijim u odnosu na ostale sisteme.
Sada kada je ceo rad spojen, više nema potrebe za iss53
granom.
Možete da zatvorite tiket u vašem sistemu za praćenje i da obrišete granu:
$ git branch -d iss53
Osnovni konflikti pri spoju
S vremena na vreme, ovaj proces neće teći ovako glatko.
Ako ste promenili isti deo istog fajla u dvema različitim granama koje spajate u jednu, Git neće moći da ih spoji kako valja.
Ako je fiks za tiket #53 modifikovao isti deo kao i hotfix
, dobićete konflikt pri spoju koji izgleda ovako nekako:
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Git nije automatski napravio novi spojni komit.
Pauzirao je proces dok vi ne rešite konflikt.
Ako želite da vidite koji fajlovi nisu spojeni bilo kada nakon konflikta pri spoju, treba da pokrenete git status
:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
Sve što ima konflikt pri spoju a nije rešeno izlistano je pod nespojeno (unmerged). Git dodaje standardne markere za rešavanje konflikta u fajlove koji imaju konflikt, da biste mogli da ih otvorite i ručno rešite konflikte. Fajl sadrži sekciju koja izgleda nekako ovako:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
Ovo znači da je verzija u HEAD
(vaša master
grana, jer to ste čekautovali kada ste pokrenuli komandu merge
) na vrhu tog bloka (sve iznad =======
), dok je verzija iz grane iss53
prikazana u donjem delu.
Da biste rešili konflikt, morate ili da izaberete jednu stranu ili drugu ili da ručno spojite sadržinu fajla.
Na primer, ovaj konflikt se može rešiti tako što ćete ceo gornji blok zameniti ovime:
<div id="footer">
please contact us at email.support@github.com
</div>
Ovo rešenje ima pomalo iz obe sekcije, a linije sa =======
i >>>>>>>
su potpuno obrisane.
Nakon što rešite svaku od ovakvih sekcija u svakom fajlu sa konfliktom, pokrenite git add
na svaki fajl da biste ga označili kao razrešen.
Stejdžovanje fajla obeležava konflikt kao razrešen u Gitu.
Ako želite da koristite grafički alat da rešite ovakve probleme, možete da pokrenete komandu git mergetool
, koja pokreće odgovarajući vizuelni alat koji vas vodi kroz konflikte:
$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (opendiff):
Ako hoćete da koristite neki drugi alat za spajanje koji nije podrazumevani (Git je izabrao opendiff
u ovom slučaju jer je komanda pokrenuta na Meku), videćete sve podržane alate izlistane na vrhu posle "one of the following tools".
Samo ukucajte ime alata koji biste radije koristili.
Note
|
Ako su vam potrebni napredniji alati da biste rešili nezgodnije konflikte pri spoju, pogledaćemo neke od njih u Advanced Merging. |
Kada izađete iz alata za rešavanje konflikta pri spoju, Git će vas pitati da li je spoj bio uspešan.
Ako kažete skripti da jeste, fajl će biti stejdžovan i označen kao razrešen.
Možete da pokrenete git status
da biste se uverili da su svi konflikti razrešeni:
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: index.html
Ako ste zadovoljni time, i ako ste potvrdili da je sve što je imalo konflikte sada na stejdžu, možete da ukucate git commit
da finalizirate spojni komit.
Podrazumevana komit poruka izgleda nekako ovako:
Merge branch 'iss53'
Conflicts:
index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: index.html
#
Možete da modifikujete tu poruku sa detaljima o tome kako ste razrešili spoj ako mislite da će to biti korisno drugima koji budu gledali ovaj spoj u budućnosti — zašto ste uradili to što ste uradili, ako nije očigledno.