Git
Chapters ▾ 2nd Edition

3.5 Větve v systému Git - Vzdálené větve

Vzdálené větve

Vzdálené reference jsou odkazy (ukazatelé) ve vašich vzdálených repozitářích a zahrnují větve, značky (tag) a další. Seznam vzdálených referencí pro vzdálené větve a také další informace můžete získat explicitním příkazem git ls-remote [vzdálený] nebo git remote show [vzdálený] [11]. Nicméně, běžnější bývá využití vzdáleně sledovaných větví.

Vzdáleně sledované větve (remote-tracking branches) jsou reference na stav vzdálených větví. Jsou to lokální reference, které nemůžete posunovat. Posunují se automaticky v době, kdy probíhá komunikace po síti. Vzdáleně sledované větve fungují jako záložky, které vám připomínají, kde byly větve ve vzdálených repozitářích v době, kdy jste se k nim naposledy připojili.

Mají podobu (vzdálený)/(větev). Pokud například chcete zjistit, jak vypadala větev master ve vašem vzdáleném repozitáři origin, když jste s ní naposledy komunikovali, budete hledat větev origin/master. Pokud pracujete s kolegou na nějakém problému a on odešle (push) větev s názvem iss53, může se stát, že i vy máte jednu z lokálních větví pojmenovanou jako iss53. Větev na serveru však ukazuje na objekt revize označený jako origin/iss53.

Mohlo by to být trochu matoucí, takže si uveďme příklad. Řekněme, že máte v síti gitový server označený git.ourcompany.com. Pokud z něj naklonujete, příkaz Gitu clone ho automaticky pojmenuje origin, stáhne z něj všechna data, vytvoří ukazatel, který bude označovat jeho větev master a lokálně ji pojmenuje origin/master. Git rovněž vytvoří vaši vlastní lokální větev master, která bude začínat ve stejném místě jako větev master serveru origin. Takže máte výchozí bod pro svou práci.

Note
Název „origin“ není nijak speciální

Stejně jako jméno větve „master“ nemá pro Git žádný speciální význam, ani název „origin“ není nijak zvláštní. Zatímco „master“ je výchozí jméno pro počáteční větev po provedení git init — což je jediný důvod, proč se tak často používá --, „origin“ je výchozí jméno pro vzdálený repozitář po provedení příkazu git clone. Pokud místo toho spustíte git clone -o booyah, dostanete jako výchozí vzdálenou větev booyah/master.

Repozitář na serveru a lokální repozitář po klonování.
Figure 30. Repozitář na serveru a lokální repozitář po klonování

Pokud budete pracovat v lokální větvi master a mezi tím někdo jiný něco odešle na git.ourcompany.com — čímž aktualizuje větev master tohoto serveru --, budou se vaše historie vyvíjet odlišně. A dokud nenavážete se serverem origin kontakt, nebude se váš ukazatel origin/master posunovat.

Lokální a vzdálená historie práce se může rozcházet.
Figure 31. Lokální a vzdálená historie práce se může rozcházet

K synchronizaci své práce použijte příkaz git fetch origin. Tento příkaz zjistí, který server je origin (v tomto případě je to git.ourcompany.com), vyzvedne z něj všechna data, která ještě nemáte, a aktualizuje vaši lokální databázi. Při tom přemístí ukazatel origin/master na novou, aktuálnější pozici.

`git fetch` aktualizuje reference do vzdáleného repozitáře.
Figure 32. git fetch aktualizuje reference do vzdáleného repozitáře

Abychom si mohli ukázat, jak se pracuje s několika vzdálenými servery a jak vypadají vzdálené větve takových vzdálených projektů, předpokládejme, že máte ještě další interní server Git, který při vývoji používá pouze jeden z vašich sprint týmů[12]. Tento server se nachází na git.team1.ourcompany.com. Můžete ho přidat jako novou vzdálenou referenci k projektu, na němž právě pracujete, spuštěním příkazu git remote add — jak jsme si ukázali v kapitole Základy práce se systémem Git. Pojmenujte tento vzdálený repozitář jako teamone, což bude zkrácený název pro celou URL adresu.

Přidání dalšího serveru v roli vzdáleného repozitáře.
Figure 33. Přidání dalšího serveru v roli vzdáleného repozitáře

Nyní můžete spustit příkaz git fetch teamone, který ze vzdáleného repozitáře teamone vyzvedne vše, co ještě nemáte. Protože je tento server podmnožinou dat, která jsou právě na serveru origin, Git nevyzvedne žádná data, ale nastaví vzdáleně sledovanou větev (remote-tracking branch) nazvanou teamone/master tak, aby ukazovala na stejný objekt revize, na který ukazuje větev master na serveru teamone.

Vzdáleně sledovaná větev pro `teamone/master`.
Figure 34. Vzdáleně sledovaná větev pro teamone/master

Odesílání

Chcete-li svou větev sdílet s okolním světem, musíte ji odeslat (push) do vzdáleného repozitáře, k němuž máte oprávnění pro zápis. Vaše lokální větve nejsou automaticky synchronizovány se vzdálenými repozitáři, do kterých zapisujete — ty, které chcete sdílet, musíte explicitně odeslat. Tímto způsobem si můžete zachovat soukromé větve pro práci, kterou nehodláte sdílet, a odesílat pouze tématické větve, na nichž chcete spolupracovat.

Máte-li větev s názvem serverfix, na níž chcete spolupracovat s ostatními, můžete ji odeslat stejným způsobem, jakým jste odesílali svou první větev. Spusťte git push <vzdálený> <větev>:

$ 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

Toto je zkrácená verze příkazu. Git automaticky rozšíří název větve serverfix na refs/heads/serverfix:refs/heads/serverfix, což znamená: „Vezmi mou lokální větev serverfix a odešli ji do vzdáleného repozitáře, kde aktualizuje tamní větev serverfix.“ Částí refs/heads/ se budeme podrobněji věnovat v kapitole Git Internals, ale nemusí být pro vás zajímavá. Můžete zadat také příkaz git push origin serverfix:serverfix, který provede totéž. Vyjadřuje: „Vezmi mou větev serverfix a udělej z ní serverfix ve vzdáleném repozitáři.“ Tento formát můžete použít k odeslání lokální větve do vzdálené větve, která se jmenuje jinak. Pokud jste nechtěli, aby se větev ve vzdáleném repozitáři jmenovala serverfix, mohli jste místo toho spustit git push origin serverfix:awesomebranch. Pak by lokální větev serverfix byla odeslána do větve awesomebranch vzdáleného projektu.

Note
Nepište pokaždé své heslo

Pokud práci odesíláte přes HTTPS URL, vyptává se vás gitový server na jméno a heslo kvůli autentizaci. Aby byl schopen zjistit, zda máte právo k odesílání (push), vypíše výzvu k zadání této informace na terminálu.

Pokud se vám to nechce zadávat při každém odesílání, můžete si nastavit „credential cache“, čili „mezipaměť pro pověřovací informace“. Nejjednodušší je podržet tyto informace pár minut v paměti, čehož snadno dosáhnete spuštěním git config --global credential.helper cache.

Více informací o různých volbách pro uchovávání pověřovacích dat naleznete v podkapitole Credential Storage.

Až bude příště některý z vašich spolupracovníků vyzvedávat data ze serveru, obdrží referenci na místo, kde se nachází serverová verze větve serverfix pod jménem vzdálené větve 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

Tady je důležité upozornit, že pokud provedete vyzvednutí (fetch), které získá i nové vzdáleně sledované větve, nezískáváte automaticky i jejich lokální, editovatelné kopie. Jinými slovy, v tomto případě nevznikne nová větev serverfix. Získáte jen ukazatel origin/serverfix, který nemůžete měnit.

Chcete-li začlenit tato data do své aktuální pracovní větve, můžete provést příkaz git merge origin/serverfix. Pokud chcete mít svou vlastní větev serverfix, na které byste mohli pracovat, můžete ji odvodit ze vzdáleně sledované větve:

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

Tímto způsobem získáte lokální větev, na níž můžete pracovat a která začíná na pozici origin/serverfix.

Sledující větve

Přepnutím (checkout) na lokální větev při odvození od vzdáleně sledované větve automaticky vzniká to, čemu se říká „sledující větev“ (a sledované větvi se říká „upstream větev“). Sledující větve jsou lokální větve s přímým vztahem ke vzdálené větvi. Pokud jste na sledující větvi a napíšete git pull, Git automaticky ví, z kterého serveru má data vyzvednout (fetch) a do jaké větve je začlenit (merge).

Pokud klonujete repozitář, většinou se vytvoří větev master, která bude sledovat větev origin/master. Ale pokud si to přejete, můžete nastavit i jiné sledující větve — takové, které budou sledovat větve v jiných vzdálených repozitářích, nebo které nebudou sledovat zrovna větev master. Jednoduchým případem je příklad, který jste právě viděli — spuštění příkazu git checkout -b [větev] [vzdálený]/[větev]. Jde o natolik běžnou operaci, že k ní Git nabízí zkratkový příkaz --track:

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

Ve skutečnosti je to tak běžná operace, že existuje dokonce zkrácená varianta pro tento zkratkový příkaz. Pokud jméno větve, na kterou se chcete přepnout (checkout) (a) dosud neexistuje a (b) přesně odpovídá jménu v jediném vzdáleném repozitáři, vytvoří Git sledující větev za vás:

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

Chcete-li nastavit lokální větev s jiným názvem, než má vzdálená větev, můžete jednoduše použít první variantu s odlišným názvem lokální větve:

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

Vaše lokální větev sf nyní bude automaticky stahovat data (pull) z origin/serverfix.

Pokud už máte lokální větev a chcete ji nastavit na vzdálenou větev, kterou jste právě stáhli (pull), nebo pokud chcete změnit upstream větev, kterou sledujete, můžete pro explicitní nastavení kdykoliv použít příkaz git branch s volbou -u nebo --set-upstream-to.

$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Note
Zkratka pro upstream

Pokud máte nastavenu sledující větev, můžete se na ni kdykoliv odkázat zkratkou @{upstream} nebo @{u}. Takže pokud jste na větvi master a ta sleduje origin/master, pak (pokud chcete) můžete místo git merge origin/master napsat git merge @{u}.

Pokud chcete vidět, jaké sledující větve máte nastaveny, můžete s příkazem git branch použít volbu -vv. Zobrazí se seznam lokálních větví s dalšími informacemi včetně toho, co každá z větví sleduje a zda má vaše lokální větev náskok, nebo je pozadu, nebo obojí.

$ 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

Takže vidíme, že naše větev iss53 sleduje origin/iss53 a má „náskok“ (ahead) dva, což znamená, že máme lokálně dva objekty revize, které ještě nebyly odeslány na server. Vidíme také, že naše větev master sleduje origin/master a její stav je aktuální. A dále vidíme, že naše větev serverfix sleduje větev server-fix-good na serveru teamone, má náskok tři a současně je pozadu o jeden, což znamená, že se na serveru nachází jeden objekt revize (commit), který jsme zatím nezačlenili (merge), a tři lokální objekty revize, které jsme zatím neodeslali (push). A na konci vidíme, že naše větev testing nesleduje žádnou vzdálenou větev.

Měli bychom poznamenat, že tato čísla se vztahují k poslednímu času, kdy jsme z každého serveru vyzvedli data (fetch). Příkaz se nesnaží o navázání kontaktu se serverem. Říká vám jen to, co je pro uvedené servery uchováno lokálně. Pokud chcete čerstvá čísla říkající, jak moc velký náskok máte a jak moc jste pozadu, musíte těsně před spuštěním tohoto příkazu vyzvednout data ze všech vzdálených repozitářů. Můžete to provést následovně: git fetch --all; git branch -vv

Stahování

Příkaz git fetch sice vyzvedne všechny změny ze serveru, které ještě nemáte, ale nijak nezmění obsah vašeho pracovního adresáře. Prostě pro vás jen vyzvedne data a sloučení nechá na vás. Ale máme tu příkaz zvaný git pull, což je ve většině případů v podstatě git fetch bezprostředně následovaný příkazem git merge. Pokud máte sledující větev nastavenou podle ukázky z minulé části — buď explicitním příkazem nebo tím, že byla vytvořena příkazy clone nebo checkout --, podívá se příkaz git pull jaký server a jakou větev vaše současná větev sleduje, vyzvedne změny ze serveru a pokusí se vzdálenou větev začlenit (merge).

Obecně bývá lepší přímo použít příkazy fetch a merge, protože magie skrytá za git pull může být často matoucí.

Mazání vzdálených větví

Dejme tomu, že máte vzdálenou větev hotovou — řekněme, že jste se spolupracovníky dokončili nějakou funkčnost a začlenili ji do větve master vašeho vzdáleného repozitáře (nebo do jiné větve, do které umísťujete stabilní kód). Vzdálenou větev můžete smazat příkazem git push s volbou --delete. Chcete-li ze serveru odstranit větev serverfix, můžete provést následující:

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

V podstatě vše, co to udělá, je jen odstranění odkazu ze serveru. Gitový server data obecně po nějakou dobu uchovává — až do doby, kdy se spustí úklid (garbage collection). Takže pokud jste něco nechtěně smazali, dá se to obvykle snadno obnovit.