Git
Chapters ▾ 2nd Edition

3.5 Grananje u Gitu - Udaljene grane

Udaljene grane

Udaljene grane su reference (pokazivači) u vašim udaljenim repozitorijumima, uključujući grane, tagove, i tako dalje. Možete da pogledate celu listu udaljenih referenci eksplicitno sa git ls-remote <remote>, ili git remote show <remote> za udaljene grane kao i za više informacija. Ipak, češći način je korišćenje udaljenih praćenih grana (remote-tracking branches).

Udaljene praćene grane su reference na stanja udaljenih grana. One su lokalne reference koje ne možete da pomerite; one se pomeraju automatski kada radite bilo kakav vid komunikacije preko mreže. Udaljene praćene grane rade kao obeleživači koji treba da vas podsete gde su grane u vašim repozitorijumima na daljinu bile kada ste se poslednji put povezali sa njima.

Uzimaju formu (remote)/(branch). Na primer, ako želite da pogledate kako je master grana na origin udaljenom repozitorijumu izgledala poslednji put kada ste stupili u komunikaciju sa njom, proverili biste origin/master granu. Ako ste radili na tiketu sa partnerom koji je slao izmene na grani iss53, vi imate svoju lokalnu granu iss53; ali grana na serveru pokazuje na komit origin/iss53.

Ovo je možda malo zbunjujuće, zato hajde da pogledamo primer. Recimo da imate Git server na svojoj mreži na git.ourcompany.com. Ako klonirate odavde, Gitova komanda clone će to automatski nazvati origin, povući će sve podatke, napraviće pokazivač na mesto gde je master grana i nazvati je origin/master lokalno. Git vam takođe daje vlastitu master granu koja počinje na istom mestu kao i origin-ova master grana, tako da imate odakle da krenete da radite.

Note
origin nije posebna grana

Kao što grana sa imenom master nema nikakvo posebno značenje na Gitu, tako nema ni origin. Dok je master podrazumevano ime za početnu granu koja se dobija sa git init i to je jedini razlog zbog koga se koristi, origin je podrazumevano ime za rimout kada pokrenete git clone. Ako pokrenete git clone -o booyah, onda će booyah/master biti podrazumevana grana na daljinu.

Server i lokalni repozitorijumi posle kloniranja.
Figure 30. Server i lokalni repozitorijumi posle kloniranja.

Ako radite nešto na lokalnoj master grani, i, u međuvremenu, neko drugi pošalje nešto na git.ourcompany.com i apdejtuje master granu, onda se vaše istorije kreću napred drugačijim tokom. Takođe, sve dok ne stupite u kontakt sa serverom, origin/master pokazivač se neće pomeriti.

Lokalni i daleki rad mogu da divergiraju.
Figure 31. Lokalni i udaljeni rad mogu da divergiraju.

Da biste sinhronizovali vaš rad, treba da pokrenete git fetch origin komandu. Ova komanda će da potraži server koji je origin (u ovom slučaju je to git.ourcompany.com), pribavi sve podatke odatle koje još uvek nemate, i apdejtuje lokalnu bazu podataka, pomerajući vaš origin/master pokazivač na novu aktuelnu poziciju.

`git fetch` apdejtuje udaljene reference.
Figure 32. git fetch apdejtuje udaljene reference

Da bismo demonstrirali situaciju sa nekoliko udaljenih servera i objasnili kako izgledaju udaljene grane za te udaljene projekte, hajde da pretpostavimo da imate još jedan interni Git server koji koristi samo jedan od vaših sprint timova. Ovaj server se nalazi na git.team1.ourcompany.com. Možete da ga dodate kao novu udaljenu referencu u projekat na kom trenutno radite tako što ćete pokrenuti git remote add kao što smo već objasnili u Osnove Gita. Ovu udaljenu granu nazovite teamone, što će predstavljati kratko ime za taj ceo URL.

DOdavanje još jednog udaljenog servera.
Figure 33. Dodavanje još jednog udaljenog servera

Sada možete da pokrenete git fetch teamone da pribavite sve što server na daljinu teamone ima a vi još uvek nemate. Pošto taj server ima podskup podataka koji origin server ima trenutno, Git ne pribavlja podatke već postavlja udaljenu praćenu granu koja se zove teamone/master koja pokazuje na komit koji teamone ima na svojoj master grani.

Udaljena praćena grana za `teamone/master`.
Figure 34. Udaljena praćena grana za teamone/master

Guranje

Kada želite da granu podelite s ostatkom sveta, morate da je gurnete ka rimoutu kome imate pristup. Vaše lokalne grane se neće automatski sinhronizovati sa rimoutovima kojima pišete - morate eksplicitno da pošaljete ("gurnete") grane koje treba da podelite. Na taj način, možete da koristite privatne grane za ono što ne želite da podelite sa ostalima, i da šaljete samo tematske grane na kojima kolaborirate.

Ako imate granu koja se zove serverfix na kojoj želite da radite sa ostalima, možete da je gurnete naviše na isti način na koji ste gurnuli i prvu granu. Pokrenite git push <remote> <branch>:

$ git push origin serverfix
Counting objects: 24, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (24/24), 1.91 KiB | 0 bytes/s, done.
Total 24 (delta 2), reused 0 (delta 0)
To https://github.com/schacon/simplegit
 * [new branch]      serverfix -> serverfix

Ovo je mala prečica. Git automatski proširuje ime grane serverfix u refs/heads/serverfix:refs/heads/serverfix, što znači "uzmi moju lokalnu serverfix granu i pošalji je kao apdejt udaljenoj servfix grani". Pogledaćemo deo refs/heads detaljnije u Git iznutra, ali u suštini možete da ga izostavite. Možete da uradite i git push origin serverfix:serverfix, što radi istu stvar — kaže "Uzmi moj serverfix i napravi ga da bude udaljen serverfix". Možete da koristite ovaj format da gurnete lokalnu granu na udaljenu granu koja se naziva drugačije. Ako ne želite da se zove serverfix na rimoutu, možete da pokrenete git push origin serverfix:awesomebranch da gurnete lokalnu serverfix granu na awesomebranch granu na udaljenom projektu.

Note
Nemojte da kucate šifru svaki put

Ako koristite HTTPS URL za guranje, Git server će vas pitati za korisničko ime i šifru radi overe autentičnosti. Po podrazumevanim podešavanjima, pitaće vas u terminalu za ovu informaciju kako bi server znao da li vam je dozvoljeno da obavite operaciju push.

Ako ne želite da kucate ove podatke svaki put kada želite to, možete da podesite "akreditivni keš". Najjednostavniji način je da ih jednostavno zadržite u memoriji na nekoliko minuta, to lako možete podesiti pokretanjem git config --global credential.helper cache.

Za više informacija o raznim akreditivnim opcijama za keširanje koje su dostupne, pogledajte Credential Storage.

Sledeći put kada jedan od vaših kolaboratora pribavi sadržaj sa servera, dobiće referencu na mesto gde je serverova verzija serverfix-a pod udaljenom granom origin/serverfix:

$ git fetch origin
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/schacon/simplegit
 * [new branch]      serverfix    -> origin/serverfix

Bitno je da primetite da kada uradite pribavljanje koje dovlači nove udaljene grane sa praćenjem, nemate automatski njihove lokalne kopije nad kojima možete da radite. Drugim rečima, u ovom slučaju, nemate novu serverfix granu - imate samo origin/serverfix pokazivač koji ne možete da menjate.

Da biste spojili ovaj sadržaj sa granom na kojoj trenutno radite, možete da pokrenete git merge origin/serverfix. Ako želite svoju ličnu serverfix granu na kojoj možete da radite, možete da je bazirate na udaljenoj praćenoj grani:

$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

Ovo vam daje lokalnu granu na kojoj možete da radite koja počinje na mestu gde je origin/serverfix.

Grane pratilje

Čekautovanje lokalne grane sa udaljene praćene grane automatski kreira nešto što se zove "grana pratilja" (ili ponekad "uzvodna grana"). Grane pratilje su lokalne grane koje imaju direktnu vezu sa udaljenom granom. Ako ste na grani pratilji i ukucate git pull, Git automatski zna sa kojeg servera treba da pribavi podatke i sa kojom granom treba da se spoji.

Kada klonirate repozitorijum, u opštem slučaju se automatski kreira master grana koja prati origin/master. Međutim, možete da postavite i druge grane za praćenje ukoliko želite — one koje prate grane na drugim rimoutovima, ili ne prate master granu. Jednostavan slučaj je primer koji ste upravo videli, pokretanje git checkout -b [branch] [remotename]/[branch]. Ova operacija je toliko česta da postoji skraćenica --track:

$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

Da biste podesili lokalnu granu sa drugim imenom od onog koje koristi udaljena grana, možete lako da iskoristite prvu verziju sa drugim imenom lokalne grane:

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'

Sada će vaša lokalna grana sf automatski povlačiti sa origin/serverfix-a.

Ako već imate lokalnu granu i želite da je podesite na udaljenu granu koju ste upravo povukli, ili želite da promenite uzvodnu granu koju pratite, možete da koristite -u ili --set-upstream-to opciju uz komandu git branch da biste joj eksplicitno zadali u bilo kom trenutku.

$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Note
upstream prečica

Kada imate podešenu granu pratilju, možete da je referencirate koristeći prečice @{upstream} ili @{u}. Znači ako ste na master grani koja prati origin/master, možete da kažete nešto kao git merge @{u} umesto git merge origin/master ukoliko želite.

Ako želite da vidite koje ste grane pratilje podesili, iskoristite -vv opciju uz git branch. Ovo će izlistati vaše lokalne grane sa više informacija, uključujući i to šta svaka od grana prati i da li je lokalna grana ispred, iza ili oba.

$ git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] forgot the brackets
  master    1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
  testing   5ea463a trying something new

Dakle, ovde možemo da vidimo da naša iss53 grana prati origin/iss53 i da je "ispred" za dva, što znači da imamo dva komita lokalno koja nisu gurnuta na server. Možemo da vidimo i to da naša master grana prati origin/master i da je to aktuelna verzija sa servera. Dalje, vidimo da naša serverfix grana prati serverfix-fix-good granu na teamone serveru i da je ispred za tri i iza za jedan, što znači da postoji jedan komit na serveru sa kojim se još nismo spojili, ali i da postoje tri komita lokalno koja još nismo gurnuli. Konačno, vidimo da naša testing grana ne prati nijednu udaljenu granu.

Važno je zapaziti da su ovi brojevi relativni u odnosu na trenutak kada ste ste poslednji put pribavili podatke sa servera. Ova komanda ne stupa u vezu sa serverom, govori vam samo o onome što lokalno ima, keširano sa servera. Ako želite aktuelne ahead i behind brojeve, moraćete da pribavite podatke sa svim rimoutova odmah pre nego što pokrenete ovu komandu. To možete uraditi na sledeći način:

$ git fetch --all; git branch -vv

Povlačenje

Dok će git fetch komanda pribaviti sve promene na serveru koje još uvek nemate, neće vam uopšte modifikovati radni direktorijum. Samo će prikupiti podatke i dozvoliće vam da ih sami spojite. Ipak, postoji komanda koja se zove git pull koja je se u većini slučajeva može protumačiti kao git fetch za kojom sledi git merge. Ako imate granu pratilju podešenu kao što je demonstrirano u prethodnom odeljku, bilo da ste je eksplicitno podesili ili ste je dobili uz clone ili checkout komandu, git pull će pogledati koji server i granu vaša grana trenutno prati, pribaviće podatke sa tog servera i onda će probati da se spoji u tu granu pratilju.

U opštem slučaju je bolje da jednostavno koristite fetch i merge komande eksplicitno, jer komanda git pull zna da bude zbunjujuća.

Brisanje udaljenih grana

Pretpostavimo da ste završili sa udaljenom granom — recimo da ste vi i vaši kolaboratori završili rad na nekom delu koda i spojili ste je sa udaljenom master granom (ili s kojom god granom spajate stabilan kod). Možete da obrišete udaljenu granu koristeći --delete opciju uz git push. Ako želite da obrišete vašu serverfix granu sa servera, pokrenite sledeće:

$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
 - [deleted]         serverfix

U suštini, ovo samo uklanja pokazivač sa servera. Gitov server će u opštem slučaju zadržati podatke tamo neko vreme dok se ne pokrene garbage collector, zato će obnova podataka biti laka ako dođe do slučajnog brisanja grane.