简体中文 ▾ 主题 ▾ 最新版本 ▾ 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 hook 的示例。

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 本身无法实现的 Git 对象连接性时,此选项很有用。在没有可靠的外部机制来确保完整可达对象连接性的情况下使用此选项,存在损坏存储库的风险,一般情况下不应使用。

PRE-RECEIVE HOOK

在任何引用被更新之前,如果 $GIT_DIR/hooks/pre-receive 文件存在且可执行,它将被调用一次,不带任何参数。hook 的标准输入将是每行一条待更新的引用信息。

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 hook 的描述。此外,证书使用 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 不同的 nonce,但来自之前的会话。请参阅 GIT_PUSH_CERT_NONCE_SLOP 环境变量。

GIT_PUSH_CERT_NONCE_SLOP

“git push --signed”发送了一个与我们当前要求发送的 nonce 不同的 nonce,但来自一个与当前会话开始时间相差此秒数的不同会话。仅当 GIT_PUSH_CERT_NONCE_STATUS 显示 SLOP 时才有意义。另请参阅 git-config[1] 中的 receive.certNonceSlop 变量。

此 hook 在任何 refname 被更新之前,以及在执行任何快进检查之前被调用。

如果 pre-receive hook 以非零退出状态退出,则不会执行任何更新,并且 update、post-receive 和 post-update hook 也不会被调用。这对于在不支持更新时快速退出非常有用。

请参阅下面的关于隔离环境的说明。

UPDATE HOOK

在每个引用被更新之前,如果 $GIT_DIR/hooks/update 文件存在且可执行,它将为每个引用调用一次,并带有三个参数:

$GIT_DIR/hooks/update refname sha1-old sha1-new

refname 参数是相对于 $GIT_DIR 的;例如,对于 master 头,它是 "refs/heads/master"。两个 sha1 参数是更新前后的 refname 的对象名称。请注意,hook 在 refname 被更新之前被调用,所以 sha1-old 要么是 0{40}(表示该引用尚不存在),要么它应该与 refname 中记录的值匹配。

如果 hook 想阻止更新指定的引用,它应该以非零状态退出。否则,它应该以零状态退出。

此 hook 的成功执行(退出状态为零)并不保证该引用实际上会被更新,它只是一个先决条件。因此,不建议从此 hook 发送通知(例如电子邮件)。请考虑改用 post-receive hook。

POST-RECEIVE HOOK

在所有引用被更新(或尝试更新)之后,如果任何引用更新成功,并且 $GIT_DIR/hooks/post-receive 文件存在且可执行,它将被调用一次,不带任何参数。hook 的标准输入将是每条成功更新的引用一行。

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 hook 一样,在接受签名推送后,可以检查 GIT_PUSH_CERT* 环境变量。

使用此 hook,可以轻松生成描述仓库更新的邮件。此示例脚本为每个引用发送一封邮件,列出推送到仓库的提交,并将签名推送的推送证书记录到日志服务。

#!/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

此 hook 调用的退出代码将被忽略,但非零退出代码将生成错误消息。

请注意,当此 hook 运行时,refname 可能没有 sha1-new。如果另一个用户在 git-receive-pack 更新了引用但 hook 能够评估它之前修改了该引用,则很容易发生这种情况。建议 hook 依赖 sha1-new 而不是 refname 的当前值。

POST-UPDATE HOOK

在所有其他处理完成后,如果至少有一个引用被更新,并且 $GIT_DIR/hooks/post-update 文件存在且可执行,则将使用已更新引用的列表调用 post-update。这可用于实现任何存储库范围的清理任务。

此 hook 调用的退出代码将被忽略;此时 git-receive-pack 唯一要做的就是退出。

此 hook 可用于,例如,如果存储库已打包并通过哑传输进行服务,则运行 git update-server-info

#!/bin/sh
exec git update-server-info

QUARANTINE ENVIRONMENT

receive-pack 接收对象时,它们被放置在 $GIT_DIR/objects 目录内的临时 "quarantine"(隔离)目录中,并且仅在 pre-receive hook 完成后才迁移到主对象存储。如果在此之前推送失败,则会完全删除临时目录。

这有几个用户可见的影响和注意事项:

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

  2. pre-receive hook 创建的任何对象都将在隔离目录中创建(仅在成功时迁移)。

  3. pre-receive hook **必须**不要将任何引用指向隔离的对象。其他访问存储库的程序将无法看到这些对象(如果 pre-receive hook 失败,这些引用将损坏)。为安全起见,来自 pre-receive 内部的任何引用更新都会被自动拒绝。

GIT

Git[1] 套件的一部分