Скотт Чакон - Pro Git
- Название:Pro Git
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Скотт Чакон - Pro Git краткое содержание
В книге рассматриваются следующие темы: основы Git;
ветвление в Git;
Git на сервере;
распределённый Git;
GitHub;
инструменты Git;
настройка Git;
Git и другие системы контроля версий.
Pro Git - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Спецификации ссылок для отправки данных на сервер
Здорово, что можно получать данные по ссылкам в отдельных пространствах имён, но нам же ещё надо сделать так, чтобы команда QA сначала смогла отправить свои ветки в пространство имён qa/. Мы решим эту задачу, используя спецификации ссылок для команды push.
Если команда QA хочет отправлять изменения из локальной ветки master в qa/master на удалённом сервере, они могут использовать такой приём:
$git push origin master:refs/heads/qa/master
Если же они хотят, чтобы Git автоматически делал так при вызове git push origin, можно добавить в конфигурационный файл значение для push:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
Опять же, это приведёт к тому, что при вызове git push origin локальная ветка master будет по умолчанию отправляться в удалённую ветку qa/master.
Удаление ссылок
Кроме того, спецификации ссылок можно использовать для удаления ссылок на удалённом сервере:
$git push origin :topic
Так как спецификация ссылки задаётся в виде :, то, пропуская , мы указываем Git, что указанную ветку на удалённом сервере надо сделать пустой, что приводит к её удалению.
Протоколы передачи данных
Git умеет передавать данные между репозиториями двумя способами: используя "глупый" и "умный" протоколы. В этой главе мы рассмотрим, как они работают.
Глупый протокол
Если вы разрешили доступ на чтение к вашему репозиторию через HTTP, то скорее всего будет использован "глупый" протокол. Протокол назвали глупым, потому что для его работы не требуется выполнение специфичных для Git операций на стороне сервера: весь процесс получения данных представляет собой серию HTTP GET запросов. При этом клиент ожидает обнаружить определённые файлы на сервере по заданным путям.
Глупый протокол довольно редко используется в наши дни. При использовании глупого протокола сложно обеспечить безопасность передачи и приватность данных, поэтому большинство Git серверов (как облачных, так и тех, что требуют установки) откажутся работать через него. Рекомендуется использовать умный протокол, который мы рассмотрим далее.
Давайте рассмотрим процесс получения данных из репозитория simplegit-progit:
$git clone http://server/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 1205815931 -0700
committer Scott Chacon 1240030591 -0700
changed the version number
Далее, необходимо загрузить ещё два объекта: дерево cfda3b — содержимое только что загруженного коммита, и 085bb3 — родительский коммит:
=> GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
(179 bytes of data)
Вот мы и получили следующий объект-коммит. Теперь содержимое коммита:
=> GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf
(404 - Not Found)
Упс, похоже, этого дерева нет на сервере в рыхлом формате, поэтому мы получили ответ 404. Возможны два варианта: объект в другом репозитории, или в упакованном файле текущего репозитория. Сначала Git проверяет список альтернативных репозиториев:
=> GET objects/info/http-alternates
(empty file)
Если бы этот запрос вернул непустой список альтернатив, Git проверил бы указанные репозитории на наличие файла в "рыхлом" формате – довольно полезная фишка для проектов-форков, позволяющая устранить дублирование. Так как в данном случае альтернатив нет, объект, должно быть, упакован в pack-файле. Чтобы посмотреть доступные на сервере pack-файлы, нужно скачать файл objects/info/packs, содержащий их список. Этот файл тоже обновляется командой update-server-info:
=> GET objects/info/packs
P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
На сервере имеется только один pack-файл, поэтому объект точно там, но необходимо проверить индексный файл, чтобы в этом убедиться. Если бы на сервере было несколько pack-файлов, загрузив сначала индексы, мы смогли бы определить, в каком именно pack-файле находится нужный нам объект:
=> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx
(4k of binary data)
Теперь, когда мы получили индекс pack-файла, можно проверить, содержится ли в нём наш объект. Это возможно благодаря тому, что в индексе хранятся SHA-1 объектов, содержащихся внутри pack-файла, а также их смещения. Наш объект там присутствует, так что продолжим и скачаем весь pack-файл:
=> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
(13k of binary data)
Итак, мы получили наше дерево, можно продолжить обход списка коммитов. Все они содержатся внутри свежескачанного pack-файла, так что снова обращаться к серверу не надо. Git извлекает рабочую копию ветки master, на которую ссылается HEAD (не забыли, для чего мы скачивали файл info/refs в самом начале?).
Умный протокол
Глупый протокол прост, но неэффективен и не позволяет производить запись в удалённые репозитории. Гораздо чаще для обмена данными используют "умный" протокол. Но это требует запуска на сервере специального процесса, знающего о структуре Git репозитория, умеющего выяснять, какие данные необходимо отправить клиенту и генерирующего отдельный pack-файл с недостающими изменениями для него. Работу умного протокола обеспечивают несколько процессов: два для отправки данных на сервер и два для загрузки с него.
Загрузка данных на сервер
Для загрузки данных на удалённый сервер используются процессы send-pack и receive-pack. Процесс send-pack запускается на клиенте и подключается к receive-pack на сервере.
SSH
Допустим, вы выполняете git push origin master и origin задан как URL, использующий протокол SSH. Git запускает процесс send-pack, который устанавливает соединение с сервером по протоколу SSH. Он пытается запустить команду на удалённом сервере через вызов ssh команды, который выглядит следующим образом:
$ssh -x git@server "git-receive-pack 'simplegit-progit.git'"
005bca82a6dff817ec66f4437202690a93763949 refs/heads/master report-status \
Читать дальшеИнтервал:
Закладка: