Спецификации ссылок
Во всей книге использовались простые связи между ветками в удалённых репозиториях и локальными ветками, но они могут быть и более сложными. Предположим, мы добавили следующий удалённый репозиторий:
$ git remote add origin git@github.com:schacon/simplegit-progit.git
Данный вызов добавляет секцию в файл .git/config
, в которой заданы имя удалённого репозитория (origin
), его URL и спецификация ссылок для извлечения данных:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
Формат спецификации следующий: опциональный +
, далее пара <src>:<dst>
, где <src>
— шаблон ссылок в удалённом репозитории, а <dst>
— соответствующий шаблон локальных ссылок. Символ +
сообщает Git’у, что обновление необходимо выполнять даже в том случае, если оно не является перемоткой.
В случае настроек по умолчанию, которые записываются во время выполнения git remote add
, Git выбирает все ссылки из refs/heads/
на стороне сервера, и записывает их в локальный каталог refs/remotes/origin/
. Таким образом, если на сервере есть ветка master
, журнал данной ветки можно получить, вызвав:
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
Все эти команды эквивалентны, так как Git развернёт каждую запись до refs/remotes/origin/master
.
Если хочется, чтобы Git забирал при обновлении только ветку master
, а не все доступные на сервере, можно изменить соответствующую строку в файле конфигурации на следующее:
fetch = +refs/heads/master:refs/remotes/origin/master
Данный refspec будет использоваться по умолчанию при вызове git fetch
для данного удалённого репозитория. Если же вам нужно изменить спецификацию всего раз, можно задать refspec в командной строке. Например, чтобы получить данные из ветки master
из удалённого репозитория в локальную origin/mymaster
, можно выполнить
$ git fetch origin master:refs/remotes/origin/mymaster
Конечно, можно задать несколько спецификаций. Получить данные нескольких веток из командной строки можно так:
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
! [rejected] master -> origin/mymaster (non fast forward)
* [new branch] topic -> origin/topic
В данном случае слияние ветки master выполнить не удалось, поскольку слияние не было просто перемоткой. Такое поведение можно изменить, добавив перед спецификацией знак +
.
В конфигурационном файле также можно задавать несколько спецификаций для получения обновлений. Чтобы каждый раз получать обновления веток master и experiment, добавьте две такие строки:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
Задавать частичные регулярные выражения в спецификации нельзя, следующая запись неверна:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
Тем не менее, можно использовать пространства имён для получения похожего результата. Если имеется команда QA (сокр. от quality assurance — контроль качества), которая использует свои несколько веток, и вы хотите получать только ветку master и все ветки команды QA, а остальные — нет, то можно добавить в конфигурацию следующее:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
Если ваш рабочий процесс является сложным, и разные команды: разработчики, тестеры, внедренцы — коммитят в разные ветки одного и того же проекта, то так вы с лёгкостью можете разделить их по разным пространствам имён.
Спецификации ссылок для команды push
Это хорошо, что мы научились получать данные по ссылкам в отдельных пространствах имён, но нам же ещё надо сделать так, чтобы команда QA сначала смогла отправить свои ветки в пространство имён qa/
. Мы решим эту задачу, используя спецификации ссылок для команды push
.
Если разработчик из команды QA хочет отправить изменения из локальной ветки master
в qa/master
на удалённом сервере, он может выполнить команду
$ git push origin master:refs/heads/qa/master
Если хочется, чтобы Git автоматически делал так при вызове git push origin
, можно добавить в конфигурационный файл значение для push
:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
Опять же, это приведёт к тому, что при вызове git push origin
локальная ветка master
будет по умолчанию отправляться в удалённую ветку qa/master
.
Удаление ссылок
Кроме всего прочего, спецификации ссылок можно использовать следующим образом для удаления ссылок на удалённом сервере:
$ git push origin :topic
Так как спецификация ссылки задаётся в виде <src>:<dst>
, опускание <src>
означает, что указанную ветку на удалённом сервере надо сделать пустой, что приводит к её удалению.