Git 🌙
Chapters ▾ 2nd Edition

3.5 Gałęzie Gita - Gałęzie zdalne

Gałęzie zdalne

Zdalne gałęzie są odnośnikami do stanu gałęzi w zdalnym repozytorium. Są to lokalne gałęzie, których nie można zmieniać; są one modyfikowane automatycznie za każdym razem, kiedy wykonujesz jakieś operacje zdalne. Zdalne gałęzie zachowują się jak zakładki przypominające ci, gdzie znajdowały się gałęzie w Twoim zdalnym repozytorium ostatnim razem, kiedy się z nim łączyłeś.

Ich nazwy przybierają następującą formę (nazwa zdalnego repozytorium)/(nazwa gałęzi). Na przykład, gdybyś chciał zobaczyć, jak wygląda gałąź master w zdalnym repozytorium origin z chwili, po raz ostatni się z nim komunikowałeś, musiałbyś sprawdzić gałąź origin/master. Jeśli na przykład pracowałeś nad zmianą wraz z partnerem który wypchnął gałąź iss53, możesz mieć lokalną gałąź iss53, ale gałąź na serwerze będzie wskazywała rewizję znajdującą się pod origin/iss53.

Może być to nieco mylące, więc przyjrzyjmy się dokładniej przykładowi Powiedzmy, że w swojej sieci masz serwer Git pod adresem git.ourcompany.com. Jeśli wykonasz z niego klonowanie repozytorium, komenda clone Gita automatycznie nazwie je dla ciebie origin, pobierze wszystkie dane, stworzy wskaźnik do miejsca gdzie znajduje się gałąź master i nazwie ją lokalnie origin/master. Ponadto Git utworzy Twoją własną lokalną gałąź master zaczynającą od tego samego miejsca, co gałąź źródła master, więc możesz natychmiast zacząć pracę.

Note
“origin” nie jest wyjątkowe

Tak jak nazwa gałęzi “master” nie ma żadnego specjalnego znaczenia w Git, tak samo “origin”. “master” jest domyślną nazwą dla gałęzi początkowej kiedy wykonasz git init, co jest jedynym powodem dla którego nazwa ta jest powszechnie używana, “origin” jest domyślną nazwą źródła kiedy wykonujesz git clone. Jeśli zamiast tego wykonasz git clone -o booyah, wtedy booyah/master będzie Twoją domyślną gałęzią zdalną.

Server and local repositories after cloning.
Figure 30. Serwer i lokalne repozytoria po klonowaniu

Jeśli wykonujesz na lokalnej gałęzi master pracę, a w międzyczasie ktoś inny wypchnie zmiany na git.ourcompany.com oraz zaktualizuje gałąź master, wówczas wasze historie przesuną się do przodu w różny sposób. Co więcej, dopóki nie skontaktujesz się z serwerem zdalnym, Twój wskaźnik origin/master nie przesunie się.

Local and remote work can diverge.
Figure 31. Lokalna i zdalna praca może się rozbiegać

Aby zsynchronizować zmiany uruchom polecenie git fetch origin. Polecenie to sprawdzi który serwer to “origin” (w tym wypadku git.ourcompany.com), pobierze z niego wszystkie dane, których jeszcze nie masz u siebie, zaktualizuje lokalną bazę, przesuwając Twój wskaźnik origin/master na nową, bardziej aktualną pozycję.

`git fetch` updates your remote references.
Figure 32. Polecenie git fetch aktualizuje zdalne referencje

Aby zademonstrować posiadanie kilku serwerów zdalnych oraz jak wyglądają gałęzie zdalne dla tych zdalnych projektów, przyjmijmy że posiadasz kolejny serwer Gita używany tylko do rozwoju przez jeden z Twoich zespołów. Ten serwer jest pod adresem git.team1.ourcompany.com. Możesz dodać go jako nowe zdalne odniesienie do projektu nad którym obecnie pracujesz poprzez wykonanie komendy git remote add jak zostało omówione w Podstawy Gita. Nazwij to odniesienie teamone, co będzie Twoim skrótem dla całego adresu URL.

Adding another server as a remote.
Figure 33. Dodanie kolejnego serwera jako zdalny

Teraz możesz wykonać git fetch teamone aby pobrać wszystko, co serwer teamone posiada, a czego dotychczas nie miałeś lokalnie. Ponieważ ten serwer posiada podzbiór danych które Twój serwer origin ma obecnie, Git nie pobiera żadnych danych, ale tworzy gałąź zdalną o nazwie teamone/master wskazującą na commit który teamone ma jako gałąź master.

Remote tracking branch for `teamone/master`.
Figure 34. Śledzenie zdalnej gałęzi dla teamone/master

Wypychanie

Kiedy chcesz podzielić się ze światem gałęzią, potrzebujesz wypchnąć ją na serwer, do którego posiadasz uprawnienia zapisu. Twoje lokalne gałęzie nie są automatycznie synchronizowane z serwerami do których zapisujesz dane - musisz jawnie wypchnąć gałęzie które chcesz udostępnić. Dzięki temu możesz używać lokalnych gałęzi których nie chcesz udostępniać do pracy, i wypychać tylko gałęzie nad którymi współpracujesz.

Jeśli posiadasz gałąź serverfix nad którą chcesz pracować z innymi, możesz wypchnąć ją w taki sam sposób, jak wypchnąłeś swoją pierwszą gałąź. Wykonaj git push (nazwa zdalnego repozytorium) (nazwa gałęzi):

$ 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

Jest to tak naprawdę skrót. Git automatycznie rozwija nazwę gałęzi serverfix do refs/heads/serverfix:refs/heads/serverfix, co oznacza “Weź moją lokalną gałąź serverfix i wypchnij ją aby zaktualizować zdalną gałąź serverfix.” W szczegółach zajmiemy się częścią refs/heads/ w rozdziale Mechanizmy wewnętrzne w Git, aczkolwiek możesz ją teraz pominąć. Możesz również wykonać git push origin serverfix:serverfix, co wykonuje to samo – mówiąc, “Weź serverfix i stwórz zdalnie serverfix.” Możesz wykorzystać ten format do wypchnięcia gałęzi lokalnej na gałąź zdalną która nazywa się inaczej. Jeśli nie chcesz nazywać jej serverfix na serwerze, możesz zamiast tego wykonać git push origin serverfix:awesomebranch aby wypchnąć lokalną gałąź serverfix na gałąź awesomebranch w projekcie zdalnym.

Note
Nie wpisuj swojego hasła za każdym razem

Jeśli używasz HTTPS URL aby wypychać zmiany, serwer Git będzie pytał o Twoją nazwę użytkownika i hasło do autoryzacji. Domyślnie zapyta poprzez terminal o te informacje aby serwer mógł odpowiedzieć czy możesz wykonać wypchnięcie.

Jeśli nie chcesz wpisywać tego za każdym razem kiedy wypychasz zmiany, możesz ustawić “cache danych autoryzacyjnych”. Najprościej jest je przechować w pamięci przez kilka minut, co możesz z łatwością ustawić wykonując git config --global credential.helper cache.

Po więcej informacji na temat dostępnych różnych opcji cache’owania, spójrz na Credential Storage.

Kiedy współpracownicy pobiorą następnym razem zmiany z serwera, otrzymają referencję do wersji serverfix na serwerze pod gałęzią 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

Ważnym jest że gdy pobierasz zmiany które przynoszą nowe gałęzie zdalne, nie posiadasz automatycznie ich lokalnych, edytowalnych kopii. Innymi słowy, w tym przypadku, nie posiadasz nowej gałęzi serverfix – posiadasz tylko wskaźnik do origin/serverfix którego nie możesz zmieniać. Aby scalić tę pracę z Twoją obecnie wybraną gałęzią, możesz wykonać git merge origin/serverfix. Jeśli chcesz swoją własną gałąź serverfix na której możesz pracować, możesz oprzeć ją o gałąź zdalną:

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

To daje gałąź lokalną na której można pracować, która rozpoczyna od miejsca, w którym znajduje się origin/serverfix.

Śledzenie gałęzi

Przełączenie się na gałąź lokalną z gałęzi zdalnej automatycznie tworzy coś, co nazywane jest “gałęzią śledzącą” (lub czasami “gałęzią upstream”). Gałęzie śledzące to lokalne gałęzie, które posiadają relację z gałęzią zdalną. Jesli jesteś na gałęzi śledzącej i wpiszesz git pull, Git automatycznie wie z którego serwera należy pobrać dane i zna gałąź którą należy scalić.

Kiedy klonujesz repozytorium, generalnie automatycznie tworzona jest gałąź master która śledzi origin/master. Aczkolwiek, możesz ustawić inne gałęzie śledzące jeśli chcesz – takie które śledzą inne, zdalne, lub nie śledzą gałęzi master. Najprostszym przypadkiem jest ten która zobaczyłeś przed chwilą, wykonując git checkout -b [gałąź] [źródłozdalne]/[gałąź]. Jest to dość powszechna operacja do której git dokłada skrót --track:

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

Aby ustawić gałąź lokalną z inną nazwą niż gałęzi zdalnej, możesz z łatwością wykorzystać pierwszą wersję z inną nazwą lokalnej gałęzi:

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

Teraz, Twoja gałąź lokalna sf będzie automatycznie pobierać zmiany z origin/servefix.

Jeśli masz już gałąź lokalną i chcesz ustawić jej śledzenie na gałąź zdalną z której właśnie pobrałeś zmiany, lub chcesz zmienić gałąź docelową którą śledzisz, możesz użyć opcji -u lub --set-upstream-to w git branch aby jawnie ustawić ją w dowolnym momencie.

$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Note
Skrót gałęzi docelowej

Jeśli masz ustawioną gałąź do śledzenia, możesz odwołać się do niej poprzez skrót @{upstream} lub @{u}. Jeśli więc jesteś na gałęzi master i śledzi ona origin/master, możesz powiedzieć coś takiego jak git merge @{u} zamiast git merge origin/master jeśli chcesz.

Jeśli chcesz zobaczyć jakie gałęzie są śledzone, możesz wykorzystać opcję -vv w git branch. Spowoduje to wyświetlenie listy lokalnych gałęzi z większą ilością informacji, włączając w to jakie gałęzie są śledzone oraz czy gałąź lokalna jest przed, za, czy na równi z gałęzią zdalną.

$ 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

Możemy tu zobaczyć że nasza gałąź iss53 śledzi origin/iss53 i jest “przed” o dwa, co oznacza że mamy dwa commity lokalnie które nie są wypchnięte na serwer. Możemy również zobaczyć że nasza gałąź master śledzi origin/master i jest aktualna. Następnie możemy zobaczyć że nasza gałąź serverfix śledzi gałąź server-fix-good na serwerze teamone i jest przed o trzy oraz za o jeden, co oznacza że jest commit na serwerze którego jeszcze nie scaliliśmy i trzy commity lokalnie których jeszcze nie wypchnęliśmy. Na koniec widzimy że nasza gałąź testing nie śledzi żadnej gałęzi zdalnej.

Ważnym jest że te cyfry oddają stan na moment ostatniego pobrania zmian z serwera. Komenda ta nie sprawdza serwerów, mówi jedynie co zostało zapamiętane na temat serwerów lokalnie. Jeśli chcesz być zupełnie na bieżąco, musisz pobrać dane ze wszystkich zdalnych źródeł tuż przed wykonaniem tego polecenia. Możesz to osiągnąć tak: $ git fetch --all; git branch -vv

Pobieranie

Gdy komenda git fetch pobierze wszystkie zmiany z serwera których dotychczas nie miałeś lokalnie, nie zmienia ona tak naprawdę danych projektu. Pobiera ona jedynie dane i pozwala scalić je we własnym zakresie. Jednakże, istnieje komenda git pull która jest tak naprawdę komendą git fetch za którą jest wykonana natychmiast komenda git merge w większości przypadków. Jeśli masz gałąź śledzącą ustawioną tak jak przedstawiono w poprzedniej sekcji, poprzez jawne ustawienie jej lub utworzenie jej przez komendy clone lub checkout, git pull będzie sprawdzać jaki serwer i gałąź śledzi obecna gałąź, pobierze zmiany z tego serwera i spróbuje scalić tę zdalną gałąź.

Zazwyczaj jest lepiej po prostu użyć komend fetch i merge jawnie, przez wzgląd na to że magia git pull może być często myląca.

Usuwanie zdalnych gałęzi

Załóżmy że skończyłeś pracę na gałęzią zdalną – powiedzmy że ty i Twoi współpracownicy zakończyliście pracę nad nową funkcją i scaliliście zmiany ze zdalną gałęzią główną master (lub jakąkolwiek inną na której znajduje się stabilna wersja kodu). Możesz usunąć zdalną gałąź wykorzystując opcję --delete w git push. Jeśli chcesz usunąć Twoją gałąź serverfix z serwera, możesz wykonać następującą komendę:

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

Najprościej mówiąc usuwa to wskaźnik z serwera. Serwer Git przechowuje dane przez jakiś czas zanim sprzątanie ruszy, więc jeśli usunięcie danych było przypadkowe, zazwyczaj jest łatwe do odzyskania.

scroll-to-top