Русский ▾ Topics ▾ Latest version ▾ git-receive-pack last updated in 2.50.0

НАЗВАНИЕ

git-receive-pack — получение того, что отправляется в репозиторий

ОБЗОР

git receive-pack <каталог-git>

ОПИСАНИЕ

Вызывается git send-pack и обновляет репозиторий информацией, полученной с внешней стороны.

Эта команда обычно не вызывается напрямую конечным пользователем. Пользовательский интерфейс для протокола находится на стороне git send-pack, и эта пара программ предназначена для отправки обновлений во внешний репозиторий. Для операций получения см. git-fetch-pack[1].

Команда позволяет создавать и выполнять перемотку вперёд ссылок sha1 (головы/метки) на внешней стороне (строго говоря, это локальная сторона, на которой работает git-receive-pack, но для пользователя, находящегося на стороне send-pack, он обновляет внешний репозиторий. Запутались?)

Существуют другие реальные примеры использования перехватчиков update и post-update в каталоге Documentation/howto.

git-receive-pack учитывает параметр конфигурации receive.denyNonFastForwards, который указывает, следует ли запрещать обновления ссылки, если они не являются перемоткой вперёд.

Доступно множество других параметров конфигурации receive.* для настройки его поведения, см. git-config[1].

ПАРАМЕТРЫ

<каталог-git>

Репозиторий, в который выполняется синхронизация.

--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-старый SP sha1-новый SP имя-ссылки LF

Значение имени ссылки относительно $GIT_DIR; например, для головы master это "refs/heads/master". Два значения sha1 перед каждым именем ссылки — это имена объектов для имени ссылки до и после обновления. Создаваемые ссылки будут иметь sha1-старый, равный 0{40}, в то время как удаляемые ссылки будут иметь sha1-новый, равный 0{40}, в противном случае sha1-старый и sha1-новый должны быть допустимыми объектами в репозитории.

При принятии подписанной отправки (см. 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? семейства команд git log (см. git-log[1]).

GIT_PUSH_CERT_NONCE

Строка одноразового числа, которую процесс попросил подписавшего включить в сертификат отправки. Если это не совпадает со значением, записанным в заголовке "nonce" сертификата отправки, это может указывать на то, что сертификат является действительным, но воспроизводится из отдельного сеанса "git push".

GIT_PUSH_CERT_NONCE_STATUS
UNSOLICITED

"git push --signed" отправил одноразовое число, когда мы не просили его отправлять.

MISSING

"git push --signed" не отправил никакого заголовка одноразового числа.

BAD

"git push --signed" отправил поддельное одноразовое число.

OK

"git push --signed" отправил одноразовое число, которое мы просили отправить.

SLOP

"git push --signed" отправил одноразовое число, отличное от того, которое мы просили отправить сейчас, но в предыдущем сеансе. См. переменную среды GIT_PUSH_CERT_NONCE_SLOP.

GIT_PUSH_CERT_NONCE_SLOP

"git push --signed" отправил одноразовое число, отличное от того, которое мы просили отправить сейчас, но в другом сеансе, время начала которого отличается от текущего сеанса на это количество секунд. Имеет смысл только когда 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 имя-ссылки sha1-старый sha1-новый

Параметр имени ссылки относительно $GIT_DIR; например, для головы master это "refs/heads/master". Два аргумента sha1 — это имена объектов для имени ссылки до и после обновления. Обратите внимание, что перехватчик вызывается до обновления имени ссылки, поэтому либо sha1-старый равен 0{40} (что означает, что такой ссылки ещё нет), либо он должен соответствовать тому, что записано в имени ссылки.

Перехватчик должен завершиться с ненулевым статусом, если он хочет запретить обновление указанной ссылки. В противном случае он должен завершиться с нулём.

Успешное выполнение (нулевой статус выхода) этого перехватчика не гарантирует, что ссылка действительно будет обновлена, это лишь предварительное условие. Поэтому отправлять уведомления (например, по электронной почте) из этого перехватчика — не очень хорошая идея. Вместо этого рассмотрите возможность использования перехватчика post-receive.

ПЕРЕХВАТЧИК POST-RECEIVE

После того как все ссылки были обновлены (или была предпринята попытка обновления), если какое-либо обновление ссылки было успешным, и если файл $GIT_DIR/hooks/post-receive существует и является исполняемым, он будет вызван один раз без параметров. Стандартный ввод перехватчика будет содержать одну строку для каждой успешно обновлённой ссылки:

sha1-старый SP sha1-новый SP имя-ссылки LF

Значение имени ссылки относительно $GIT_DIR; например, для головы master это "refs/heads/master". Два значения sha1 перед каждым именем ссылки — это имена объектов для имени ссылки до и после обновления. Созданные ссылки будут иметь sha1-старый, равный 0{40}, в то время как удалённые ссылки будут иметь sha1-новый, равный 0{40}, в противном случае sha1-старый и sha1-новый должны быть допустимыми объектами в репозитории.

Переменные среды GIT_PUSH_CERT* можно проверить, как и в перехватчике pre-receive, после принятия подписанной отправки.

Используя этот перехватчик, легко создавать письма, описывающие обновления репозитория. Этот пример сценария отправляет одно почтовое сообщение на ссылку, перечисляя коммиты, отправленные в репозиторий, и регистрирует сертификаты отправки подписанных отправок с правильными подписями в службе журналирования:

#!/bin/sh
# отправить по почте информацию об обновлении коммита.
while read oval nval ref
do
	if expr "$oval" : '0*$' >/dev/null
	then
		echo "Создана новая ссылка со следующими коммитами:"
		git rev-list --pretty "$nval"
	else
		echo "Новые коммиты:"
		git rev-list --pretty "$nval" "^$oval"
	fi |
	mail -s "Изменения в ссылке $ref" commit-list@mydomain
done
# зарегистрировать подписанный сертификат отправки, если есть
if test -n "${GIT_PUSH_CERT-}" && test ${GIT_PUSH_CERT_STATUS} = G
then
	(
		echo ожидаемое одноразовое число: ${GIT_PUSH_NONCE}
		git cat-file blob ${GIT_PUSH_CERT}
	) | mail -s "сертификат отправки от $GIT_PUSH_CERT_SIGNER" push-log@mydomain
fi
exit 0

Код выхода из этого вызова перехватчика игнорируется, однако ненулевой код выхода приведёт к созданию сообщения об ошибке.

Обратите внимание, что возможно, что имя ссылки не будет иметь sha1-новый, когда этот перехватчик запускается. Это легко может произойти, если другой пользователь изменяет ссылку после того, как она была обновлена git-receive-pack, но до того, как перехватчик смог её оценить. Рекомендуется, чтобы перехватчики полагались на sha1-новый, а не на текущее значение имени ссылки.

ПЕРЕХВАТЧИК 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. Если отправка завершится ошибкой до этого, временный каталог будет полностью удалён.

Это имеет несколько заметных для пользователя эффектов и предостережений:

  1. Отправки, которые завершаются ошибкой из-за проблем с входящим пакетом, отсутствующих объектов или из-за перехватчика pre-receive, не оставляют никаких данных на диске. Обычно это полезно для предотвращения заполнения диска повторяющимися неудачными отправками, но может усложнить отладку.

  2. Любые объекты, созданные перехватчиком pre-receive, будут созданы в изолированном каталоге (и будут перемещены, только если он завершится успешно).

  3. Перехватчик pre-receive НЕ ДОЛЖЕН обновлять какие-либо ссылки, чтобы они указывали на изолированные объекты. Другие программы, обращающиеся к репозиторию, не смогут увидеть эти объекты (и если перехватчик pre-receive завершится ошибкой, эти ссылки будут повреждены). Для безопасности любые обновления ссылок изнутри pre-receive автоматически отклоняются.

GIT

Является частью пакета git[1]