Удалённые ветки — это ссылки на состояние веток в ваших удалённых репозиториях. Это локальные ветки, которые нельзя перемещать; они двигаются автоматически всякий раз, когда вы осуществляете связь по сети. Удалённые ветки действуют как закладки для напоминания о том, где ветки в удалённых репозиториях находились во время последнего подключения к ним.
Они выглядят как (имя удал. репоз.)/(ветка)
. Например,
если вы хотите посмотреть, как выглядела ветка master
на
сервере origin
во время последнего соединения с ним,
проверьте ветку origin/master
. Если вы с партнёром работали
над одной проблемой, и он выложил ветку iss53
, у вас может
быть своя локальная ветка iss53
; но та ветка на сервере
будет указывать на коммит в origin/iss53
.
Всё это, возможно, сбивает с толку, поэтому давайте рассмотрим пример.
Скажем, у вас в сети есть свой Git-сервер на git.ourcompany.com
.
Если вы с него что-то склонируете (clone), Git автоматически назовёт его
origin
, заберёт оттуда все данные, создаст указатель на то,
на что там указывает ветка master
, и назовёт его локально
origin/master
(но вы не можете его двигать). Git также сделает
вам вашу собственную ветку master
, которая будет начинаться
там же, где и ветка master
в origin, так что вам будет с чем
работать (см. рис. 3-22).
Если вы сделаете что-то в своей локальной ветке master
, а
тем временем кто-то ещё отправит (push) изменения на git.ourcompany.com
и обновит там ветку master
, то ваши истории продолжатся по-разному.
Ещё, до тех пор, пока вы не свяжетесь с сервером origin, ваш указатель
origin/master
не будет сдвигаться (см. рис. 3-23).
Для синхронизации вашей работы выполняется команда git fetch origin
.
Эта команда ищет, какому серверу соответствует origin (в нашем случае это
git.ourcompany.com
); извлекает оттуда все данные, которых у вас
ещё нет, и обновляет ваше локальное хранилище данных; сдвигает указатель
origin/master
на новую позицию (см. рис. 3-24).
Чтобы продемонстрировать то, как будут выглядеть удалённые ветки в
ситуации с несколькими удалёнными серверами, предположим, что у вас есть
ещё один внутренний Git-сервер, который используется для разработки
только одной из ваших команд разработчиков. Этот сервер находится на
git.team1.ourcompany.com
. Вы можете добавить его в качестве
новой удалённой ссылки на проект, над которым вы сейчас работаете с
помощью команды git remote add
так же, как было описано в
главе 2. Дайте этому удалённому серверу имя teamone
, которое
будет сокращением для полного URL (см. рис. 3-25).
Теперь можете выполнить git fetch teamone
, чтобы извлечь
всё, что есть на сервере и нет у вас. Так как в данный момент на этом
сервере есть только часть данных, которые есть на сервере origin
,
Git не получает никаких данных, но выставляет удалённую ветку с именем
teamone/master
, которая указывает на тот же коммит, что и
ветка master
на сервере teamone
(см. рис. 3-26).
Когда вы хотите поделиться веткой с окружающими, вам необходимо отправить (push) её на удалённый сервер, на котором у вас есть права на запись. Ваши локальные ветки автоматически не синхронизируются с удалёнными серверами — вам нужно явно отправить те ветки, которыми вы хотите поделиться. Таким образом, вы можете использовать свои личные ветки для работы, которую вы не хотите показывать, и отправлять только те тематические ветки, над которыми вы хотите работать с кем-то совместно.
Если у вас есть ветка serverfix
, над которой вы хотите
работать с кем-то ещё, вы можете отправить её точно так же, как вы
отправляли вашу первую ветку. Выполните git push (удал. сервер) (ветка)
:
$ git push origin serverfix
Counting objects: 20, done.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (15/15), 1.74 KiB, done.
Total 15 (delta 5), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new branch] serverfix -> serverfix
Это в некотором роде сокращение. Git автоматически разворачивает имя
ветки serverfix
до refs/heads/serverfix:refs/heads/serverfix
,
что означает “возьми мою локальную ветку serverfix и обнови из неё удалённую
ветку serverfix”. Мы подробно обсудим часть с refs/heads/
в главе 9,
но обычно её можно опустить. Вы также можете выполнить
git push origin serverfix:serverfix
— произойдёт то же самое — здесь говорится “возьми мой serverfix и
сделай его удалённым serverfix”. Можно использовать этот формат для
отправки локальной ветки в удалённую ветку с другим именем. Если вы не
хотите, чтобы ветка называлась serverfix
на удалённом сервере,
то вместо предыдущей команды выполните git push origin serverfix:awesomebranch
.
Так ваша локальная ветка serverfix
отправится в ветку awesomebranch
удалённого проекта.
В следующий раз, когда один из ваших соавторов будет получать обновления с сервера,
он получит ссылку на то, на что указывает serverfix
на сервере, как
удалённую ветку origin/serverfix
:
$ git fetch origin
remote: Counting objects: 20, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 15 (delta 5), reused 0 (delta 0)
Unpacking objects: 100% (15/15), done.
From git@github.com:schacon/simplegit
* [new branch] serverfix -> origin/serverfix
Важно отметить, что когда при получении данных у вас появляются новые
удалённые ветки, вы не получаете автоматически для них локальных
редактируемых копий. Другими словами, в нашем случае вы не получите
новую ветку serverfix
— только указатель origin/serverfix
,
который вы не можете менять.
Чтобы слить эти наработки в свою текущую рабочую ветку, выполните
git merge origin/serverfix
. Если вам нужна своя собственная
ветка serverfix
, над которой вы сможете работать, то вы можете
создать её на основе удалённой ветки:
$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "serverfix"
Это даст вам локальную ветку, на которой можно работать. Она будет
начинаться там, где и origin/serverfix
.
Получение локальной ветки с помощью git checkout
из удалённой
ветки автоматически создаёт то, что называется отслеживаемой веткой.
Отслеживаемые ветки — это локальные ветки, которые напрямую связаны с
удалённой веткой. Если, находясь на отслеживаемой ветке, вы наберёте
git push
, Git уже будет знать, на какой сервер и в какую ветку
отправлять изменения. Аналогично выполнение git pull
на одной из таких веток сначала получает все удалённые ссылки, а затем
автоматически делает слияние с соответствующей удалённой веткой.
При клонировании репозитория, как правило, автоматически создаётся ветка
master
, которая отслеживает origin/master
, поэтому
git push
и git pull
работают для этой ветки "из коробки" и не требуют дополнительных
аргументов. Однако, вы можете настроить отслеживание и других веток
удалённого репозитория. Простой пример, как это сделать, вы увидели
только что — git checkout -b [ветка] [удал. сервер]/[ветка]
. Если вы используете Git версии 1.6.2 или более позднюю, можете также воспользоваться сокращением --track
:
$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "serverfix"
Чтобы настроить локальную ветку с именем, отличным от имени удалённой ветки, вы можете легко использовать первую версию с другим именем локальной ветки:
$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "sf"
Теперь ваша локальная ветка sf будет автоматически отправлять (push) и получать (pull) изменения из origin/serverfix.
Скажем, вы и ваши соавторы закончили с нововведением и слили его в ветку master
на удалённом сервере (или в какую-то другую ветку, где хранится
стабильный код). Вы можете удалить ветку на удалённом сервере, используя
несколько бестолковый синтаксис git push [удал. сервер] :[ветка]
. Чтобы удалить ветку serverfix
на сервере, выполните следующее:
$ git push origin :serverfix
To git@github.com:schacon/simplegit.git
- [deleted] serverfix
Хлоп. Нет больше ветки на вашем сервере. Вам может захотеться сделать
закладку на текущей странице, так как эта команда вам понадобится, а
синтаксис вы, скорее всего, забудете. Можно запомнить эту команду
вернувшись к синтаксису git push [удал. сервер] [лок. ветка]:[удал. ветка]
, который мы рассматривали немного раньше. Опуская часть [лок. ветка]
, вы, по сути, говорите “возьми ничто в моём репозитории и сделай так, чтобы в [удал. ветка]
было то же самое”.