简体中文 ▾ 主题 ▾ 最新版本 ▾ git-receive-pack 最后更新于 2.50.0

名称

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 端的用户而言,它是在更新远程。感到困惑吗?)

在 Documentation/howto 目录中可以找到其他使用 update 和 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

--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"。每个 refname 前的两个 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 密钥 ID。

GIT_PUSH_CERT_STATUS

推送证书 GPG 验证的状态,使用与 git log 系列命令的 %G? 格式中使用的相同的助记符(参见 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 时才有效。另请阅读 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 头,它是 "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 头,它是 "refs/heads/master"。每个 refname 前的两个 sha1 值是更新前后 refname 的对象名称。已创建的引用将具有 sha1-old 等于 0{40},而已删除的引用将具有 sha1-new 等于 0{40},否则 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 唯一剩下的事情就是自己退出。

例如,如果仓库已打包并通过 dumb 传输提供服务,则此钩子可用于运行 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