В данном случае, слияние ветки 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> означает, что указанную ветку на удалённом сервере надо сделать пустой, что приводит к её удалению.
Протоколы передачи
Git может передавать данные между репозиториями одним из двух основных способов: через HTTP или через "умные" протоколы для транспортов file://, ssh:// и git://. В данном разделе мы кратко рассмотрим как эти два протокола работают.
Тупой протокол
Git-транспорт работающий по HTTP часто называют "тупым" протоколом, потому что для его работы во время передачи данных не требуется исполнения никакого Git-специфичного кода на стороне сервера. Процесс извлечения данных представляет собой последовательность GET-запросов, клиент обращается к стандартной структуре каталогов Git. Давайте рассмотрим процесс получения данных по HTTP на примере библиотеки simplegit:
$ git clone http://github.com/schacon/simplegit-progit.git
Первое действие, выполняемое данной командой — загрузка файла info/refs. Данный файл записывается командой update-server-info, поэтому для использования HTTP-транспорта необходимо запускать эту команду в post-receive хуке:
=> GET info/refs ca82a6dff817ec66f44342007202690a93763949 refs/heads/master
Теперь у нас имеется список удалённых веток и их хеши. Далее, нам надо посмотреть куда ссылается HEAD, чтобы знать на какую версию переключиться после завершения работы команды.
=> GET HEAD ref: refs/heads/master
Нам надо переключиться на ветку master после завершения процесса. На данном этапе можно начать обход дерева. Начальной точкой является объект-коммит ca82a6, о чём мы узнали из файла info/refs, и мы начинаем с его загрузки:
=> GET objects/ca/82a6dff817ec66f44342007202690a93763949 (179 bytes of binary data)
Объект получен, он был в рыхлом формате на сервере, и мы получили его по HTTP используя статический GET-запрос. Теперь можно его разархивировать, отрезать заголовок и посмотреть на его содержимое:
$ git cat-file -p ca82a6dff817ec66f44342007202690a93763949 tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf parent 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 author Scott Chacon <schacon@gmail.com> 1205815931 -0700 committer Scott Chacon <schacon@gmail.com> 1240030591 -0700 changed the version number
Далее, необходимо загрузить ещё два объекта: cfda3b — объект-дерево, который обозначен как содержимое только что загруженного коммита, и 085bb3 — родительский коммит:
=> GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 (179 bytes of data)