English ▾ 主题 ▾ 最新版本 ▾ git-receive-pack 上次更新于 2.43.0

名称

git-receive-pack - 接收推送到仓库的内容

概要

git receive-pack <git-dir>

描述

git send-pack 调用,并使用来自远程端的信息更新仓库。

此命令通常不由最终用户直接调用。协议的用户界面在 git send-pack 端,该程序对旨在用于将更新推送到远程仓库。 对于拉取操作,请参阅 git-fetch-pack[1]

该命令允许在远程端(严格来说,是本地端 git-receive-pack 运行,但是对于坐在 send-pack 端的用户来说,它正在更新远程端。 困惑了吗?)创建和快进 sha1 引用(heads/tags)。

在 Documentation/howto 目录中可以找到使用更新和 post-update 钩子的其他真实示例。

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 请求。 请参阅 git-upload-pack[1] 中的 --http-backend-info-refs

PRE-RECEIVE 钩子

在更新任何引用之前,如果 $GIT_DIR/hooks/pre-receive 文件存在且可执行,则将调用它一次,不带任何参数。 钩子的标准输入将是每行一个要更新的引用

sha1-old SP sha1-new SP refname LF

refname 值是相对于 $GIT_DIR 的; 例如,对于 master head,这是 "refs/heads/master"。 每个 refname 之前的两个 sha1 值是更新前后 refname 的对象名称。 要创建的引用将具有等于 0{40} 的 sha1-old,而要删除的引用将具有等于 0{40} 的 sha1-new,否则 sha1-old 和 sha1-new 应该是仓库中的有效对象。

当接受签名推送(请参阅 git-push[1])时,签名的推送证书存储在 blob 中,并且可以查阅环境变量 GIT_PUSH_CERT 以获取其对象名称。 有关示例,请参见 post-receive 钩子的描述。 此外,证书已使用 GPG 验证,并且结果通过以下环境变量导出

GIT_PUSH_CERT_SIGNER

签署推送证书的密钥所有者的姓名和电子邮件地址。

GIT_PUSH_CERT_KEY

签署推送证书的密钥的 GPG 密钥 ID。

GIT_PUSH_CERT_STATUS

推送证书的 GPG 验证状态,使用与 git log 系列命令的 %G? 格式中使用的助记符相同的助记符(请参阅 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 时才有意义。 另请阅读 git-config[1] 中的 receive.certNonceSlop 变量。

在更新任何 refname 之前,以及在执行任何快进检查之前,都会调用此钩子。

如果 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 head,这是 "refs/heads/master"。 两个 sha1 参数是更新前后 refname 的对象名称。 请注意,钩子在 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 head,这是 "refs/heads/master"。 每个 refname 之前的两个 sha1 值是更新前后 refname 的对象名称。 已创建的引用将具有等于 0{40} 的 sha1-old,而已删除的引用将具有等于 0{40} 的 sha1-new,否则 sha1-old 和 sha1-new 应该是仓库中的有效对象。

接受签名推送后,可以像在 pre-receive 钩子中一样,检查 GIT_PUSH_CERT* 环境变量。

使用此钩子,很容易生成描述仓库更新的邮件。 此示例脚本为每个引用发送一封邮件,列出已推送到仓库的提交,并将签名良好的推送的推送证书记录到记录器服务

#!/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 钩子完成后才会迁移到主对象存储中。 如果推送在此之前失败,则临时目录将被完全删除。

这有一些用户可见的效果和警告

  1. 由于传入包的问题,缺少对象或由于 pre-receive 钩子而导致的推送失败将不会留下任何磁盘数据。 这通常有助于防止重复失败的推送填满你的磁盘,但会使调试更具挑战性。

  2. pre-receive 钩子创建的任何对象都将在隔离目录中创建(并且仅在其成功时才进行迁移)。

  3. pre-receive钩子程序不得更新任何引用来指向隔离的对象。 访问该仓库的其他程序将无法看到这些对象(并且如果 pre-receive 钩子程序失败,这些引用将会损坏)。 为了安全起见,来自 pre-receive 的任何引用更新都会被自动拒绝。

GIT

属于 git[1] 套件的一部分

scroll-to-top