git-receive-pack
Имя
git-receive-pack — получает данные, отправленные в репозиторий
Сводка
git receive-pack <git-dir>
Описание
Вызывается командой git send-pack и обновляет репозиторий данными, переданными с удалённой стороны.
Эта команда обычно не вызывается конечным пользователем напрямую. Пользовательский интерфейс протокола находится на стороне git send-pack, а эта пара программ предназначена для отправки обновлений в удалённый репозиторий. О командах для получения изменений см. git-fetch-pack[1].
Команда позволяет создавать и перематывать вперёд ссылки sha1 (heads/tags) на удалённой стороне (строго говоря, её запускает локальная сторона git-receive-pack, но для пользователя, работающего со стороны send-pack, обновляется удалённый репозиторий. Запутались?)
Другие реальные примеры использования хуков update и post-update можно найти в каталоге Documentation/howto.
git-receive-pack учитывает параметр конфигурации receive.denyNonFastForwards, который определяет, следует ли запрещать обновления ссылки, если они не являются перемоткой вперёд.
Для настройки поведения доступны и другие параметры конфигурации receive.*; см. git-config[1].
Параметры
- <git-dir>
-
Репозиторий, в который выполняется синхронизация.
- --http-backend-info-refs
-
Используется командой git-http-backend[1] для обработки запросов $GIT_URL/info/refs?service=git-receive-pack. См.
--http-backend-info-refsв git-upload-pack[1]. - --skip-connectivity-check
-
Пропускает проверки связности, подтверждающие существование всех объектов в транзитивном замыкании достижимых объектов. Этот параметр предназначен для операторов серверов, которые хотят реализовать собственную проверку связности объектов за пределами Git. Это полезно в случаях, когда серверная сторона располагает дополнительной информацией о способе использования Git и поэтому может полагаться на определённые гарантии, чтобы эффективнее вычислять связность объектов, которые сам Git не может гарантировать. Использование этого параметра без надёжного внешнего механизма обеспечения полной связности достижимых объектов может привести к повреждению репозитория; в общем случае его использовать не следует.
Хук pre-receive
Перед обновлением любой ссылки, если файл $GIT_DIR/hooks/pre-receive существует и является исполняемым, он будет вызван один раз без параметров. Стандартный ввод хука будет содержать по одной строке для каждой обновляемой ссылки:
sha1-old SP sha1-new SP refname LF
Значение refname указывается относительно $GIT_DIR; например, для заголовка master это "refs/heads/master". Два значения sha1 перед каждым refname — это имена объектов, на которые ссылалось имя до и после обновления. Для создаваемых ссылок sha1-old будет равен 0{40}, а для удаляемых ссылок sha1-new будет равен 0{40}; в противном случае sha1-old и sha1-new должны быть действительными объектами в репозитории.
При принятии подписанной отправки (см. git-push[1]) сертификат подписанной отправки сохраняется в blob, а его имя объекта можно получить из переменной среды GIT_PUSH_CERT. Пример см. в описании хука post-receive. Кроме того, сертификат проверяется с помощью GPG, а результат передаётся в следующих переменных среды:
-
GIT_PUSH_CERT_SIGNER -
Имя и адрес электронной почты владельца ключа, которым подписан сертификат отправки.
-
GIT_PUSH_CERT_KEY -
Идентификатор ключа GPG, которым подписан сертификат отправки.
-
GIT_PUSH_CERT_STATUS -
Статус проверки сертификата отправки с помощью GPG. Используются те же мнемонические обозначения, что и в формате %G? семейства команд
gitlog(см. git-log[1]). -
GIT_PUSH_CERT_NONCE -
Строка nonce, которую процесс попросил подписывающего включить в сертификат отправки. Если она не совпадает со значением, записанным в заголовке "nonce" сертификата отправки, это может указывать на то, что действительный сертификат повторно используется из отдельного сеанса "git push".
-
GIT_PUSH_CERT_NONCE_STATUS -
-
UNSOLICITED -
"git push --signed" отправила nonce, хотя мы не просили этого делать.
-
MISSING -
"git push --signed" не отправила заголовок nonce.
-
BAD -
"git push --signed" отправила неверный nonce.
-
OK -
"git push --signed" отправила nonce, который мы просили отправить.
-
SLOP -
"git push --signed" отправила nonce, отличный от того, который мы попросили отправить сейчас, но использовавшийся в предыдущем сеансе. См. переменную среды
GIT_PUSH_CERT_NONCE_SLOP.
-
-
GIT_PUSH_CERT_NONCE_SLOP -
"git push --signed" отправила nonce, отличный от того, который мы попросили отправить сейчас, но использовавшийся в другом сеансе, время начала которого отличается от времени начала текущего сеанса на указанное число секунд. Имеет смысл только тогда, когда
GIT_PUSH_CERT_NONCE_STATUSсодержит значениеSLOP. Также см. описание переменнойreceive.certNonceSlopв git-config[1].
Этот хук вызывается до обновления любого имени ссылки и до выполнения любых проверок перемотки вперёд.
Если хук pre-receive завершится с ненулевым кодом, обновления выполняться не будут, а хуки update, post-receive и post-update также не будут вызваны. Это может быть полезно, чтобы быстро прервать выполнение, если обновление не должно поддерживаться.
См. примечания об изолированной среде ниже.
Хук update
Перед обновлением каждой ссылки, если файл $GIT_DIR/hooks/update существует и является исполняемым, он будет вызываться отдельно для каждой ссылки с тремя параметрами:
$GIT_DIR/hooks/update refname sha1-old sha1-new
Параметр refname указывается относительно $GIT_DIR; например, для заголовка master это "refs/heads/master". Два аргумента sha1 — это имена объектов, на которые ссылалось имя до и после обновления. Обратите внимание, что хук вызывается до обновления refname, поэтому sha1-old либо равен 0{40} (что означает, что такой ссылки ещё нет), либо должен совпадать со значением, записанным в refname.
Если хук хочет запретить обновление указанной ссылки, он должен завершиться с ненулевым статусом. В противном случае он должен завершиться с нулевым статусом.
Успешное выполнение этого хука (с нулевым кодом завершения) не гарантирует, что ссылка действительно будет обновлена, а является лишь необходимым условием. Поэтому отправлять уведомления (например, по электронной почте) из этого хука не рекомендуется. Вместо него рассмотрите возможность использования хука post-receive.
Хук post-receive
После обновления всех ссылок (или попыток их обновления), если хотя бы одно обновление ссылки прошло успешно и файл $GIT_DIR/hooks/post-receive существует и является исполняемым, он будет вызван один раз без параметров. Стандартный ввод хука будет содержать по одной строке для каждой успешно обновлённой ссылки:
sha1-old SP sha1-new SP refname LF
Значение refname указывается относительно $GIT_DIR; например, для заголовка master это "refs/heads/master". Два значения sha1 перед каждым refname — это имена объектов, на которые ссылалось имя до и после обновления. Для созданных ссылок sha1-old будет равен 0{40}, а для удалённых ссылок sha1-new будет равен 0{40}; в противном случае sha1-old и sha1-new должны быть действительными объектами в репозитории.
После принятия подписанной отправки можно просмотреть переменные среды GIT_PUSH_CERT*, как и в хуке pre-receive.
С помощью этого хука легко формировать письма с описанием обновлений репозитория. Этот пример сценария отправляет отдельное письмо для каждой ссылки со списком коммитов, отправленных в репозиторий, и записывает сертификаты подписанных отправок с действительными подписями в службу журналирования:
#!/bin/sh
# mail out commit update information.
while read oval nval ref
do
if expr "$oval" : '0*$' >/dev/null
then
echo "Created a new ref, with the following commits:"
git rev-list --pretty "$nval"
else
echo "New commits:"
git rev-list --pretty "$nval" "^$oval"
fi |
mail -s "Changes to ref $ref" commit-list@mydomain
done
# log signed push certificate, if any
if test -n "${GIT_PUSH_CERT-}" && test ${GIT_PUSH_CERT_STATUS} = G
then
(
echo expected nonce is ${GIT_PUSH_NONCE}
git cat-file blob ${GIT_PUSH_CERT}
) | mail -s "push certificate from $GIT_PUSH_CERT_SIGNER" push-log@mydomain
fi
exit 0 Код завершения этого вызова хука игнорируется, однако ненулевой код завершения приведёт к выводу сообщения об ошибке.
Обратите внимание, что во время выполнения этого хука у refname может отсутствовать sha1-new. Такое легко может произойти, если другой пользователь изменит ссылку после её обновления командой git-receive-pack, но до того, как хук успеет её обработать. Рекомендуется, чтобы хуки использовали sha1-new, а не текущее значение refname.
Хук post-update
После завершения всей остальной обработки, если была обновлена хотя бы одна ссылка и файл $GIT_DIR/hooks/post-update существует и является исполняемым, post-update будет вызван со списком обновлённых ссылок. Это можно использовать для выполнения задач очистки всего репозитория.
Код завершения этого вызова хука игнорируется; на этом этапе git-receive-pack остаётся только завершить работу.
Например, этот хук можно использовать для запуска git update-server-info, если репозиторий упакован и обслуживается с помощью простого транспорта.
#!/bin/sh exec git update-server-info
Изолированная среда
Когда receive-pack получает объекты, они помещаются во временный каталог «карантина» внутри каталога $GIT_DIR/objects и переносятся в основное хранилище объектов только после завершения хука pre-receive. Если до этого момента отправка завершится неудачей, временный каталог будет полностью удалён.
Это имеет несколько заметных для пользователя последствий и особенностей:
-
Отправки, завершившиеся неудачей из-за проблем с входящим пакетом, отсутствующих объектов или хука
pre-receive, не оставят данных на диске. Обычно это помогает предотвратить заполнение диска из-за повторных неудачных отправок, но может усложнить отладку. -
Все объекты, созданные хуком
pre-receive, будут созданы в каталоге карантина (и перенесены только в случае успешного завершения хука). -
Хук
pre-receiveНЕ ДОЛЖЕН обновлять ссылки, чтобы они указывали на объекты в карантине. Другие программы, обращающиеся к репозиторию, не смогут видеть эти объекты (а если хук pre-receive завершится неудачей, такие ссылки окажутся повреждёнными). Для безопасности любые обновления ссылок изpre-receiveавтоматически отклоняются.
См. также
receive-pack
© 2005–2026 Linus Torvalds and others
Licensed under the GNU General Public License version 2.
https://git-scm.com/docs/git-receive-pack