git receive-pack
名称
git-receive-pack - 接收推入存储库的内容
概要
git-receive-pack <directory>
描述
git send-pack
使用从远程端提供的信息调用并更新存储库。
该命令通常不由最终用户直接调用。该协议的用户界面位于git send-pack
侧面,程序对旨在用于将更新推送到远程存储库。对于拉操作,请参阅git-fetch-pack。
该命令允许在远端创建和快速转发sha1 refs(heads/tags)(严格来说,这是本地最终git-receive-pack
运行,但对于坐在发送包端的用户,它正在更新遥远的。)
在Documentation/howto目录中还有其他一些使用update和post-update钩子的真实例子。
git-receive-pack
尊重receive.denyNonFastForwards配置选项,该选项告诉它是否应该拒绝对ref的更新,如果它们不是快进的。
其他一些receive.* config选项可用于调整其行为,请参阅git-config。
选项
<directory>
要同步到的存储库。
预接收hook
在任何ref被更新之前,如果$ GIT_DIR/hooks/pre-receive文件存在并且是可执行文件,它将被调用一次而没有参数。钩子的标准输入将被更新为每个参考线一行:
sha1-old SP sha1-new SP refname LF
refname的值是相对于$ GIT_DIR; 例如,对于主人的头,这是“裁判/头/主人”。每个refname前的两个sha1值是更新之前和之后的refname的对象名称。要创建的引用将具有等于0 {40}的sha1,而要删除的引用将具有等于0 {40}的sha1-new,否则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验证推送证书的状态,使用与命令系列%G?
格式相同的助记符git log
(请参阅git-log)。
GIT_PUSH_CERT_NONCE
进程要求签名者将其包含在推送证书中的随机数字符串。如果这与推送证书中的“随机数”头中记录的值不匹配,则可能表明证书是从单独的“git推送”会话重播的有效证书。
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中阅读有关变量。
在更新任何refname之前和执行任何快进检查之前调用此钩子。
如果预接收hook以非零退出状态退出,则不会执行更新,更新,接收后和更新后钩子也不会被调用。如果更新不被支持,这可以快速救助。
请参阅下面的隔离环境注意事项。
更新hook
在更新每个ref之前,如果$ GIT_DIR/hooks/update文件存在并且是可执行文件,则每个ref都会调用一次,其中包含三个参数:
$GIT_DIR/hooks/update refname sha1-old sha1-new
refname参数是相对于$ GIT_DIR; 例如,对于主人的头,这是“refs/heads/master”。这两个sha1参数是更新之前和之后refname的对象名称。请注意,钩子在更新refname之前被调用,所以sha1-old是0 {40}(意味着还没有这样的ref),或者它应该匹配在refname中记录的内容。
如果要禁止更新指定的参考值,则hook应该以非零状态退出。否则它应该以零退出。
hook的成功执行(零退出状态)并不能确保引用实际上会被更新,它只是一个先决条件。因此,从这个hook发送通知(例如电子邮件)并不是一个好主意。考虑使用post-receive hook来代替。
接收后hook
在所有ref被更新(或试图更新)之后,如果任何ref更新成功,并且$ GIT_DIR/hooks/post-receive文件存在并且是可执行文件,则它将被调用一次而没有参数。钩子的标准输入对于每个成功更新的ref都是一行:
sha1-old SP sha1-new SP refname LF
refname的值是相对于$ GIT_DIR; 例如,对于主人的头,这是“refs/heads/master”。每个refname前的两个sha1值是更新之前和之后的refname的对象名称。创建的Ref将具有等于0 {40}的sha1等号,而被删除的ref将具有等于0 {40}的sha1-new,否则sha1-old和sha1-new应该是存储库中的有效对象。
在GIT_PUSH_CERT*
环境变量可以被检查,就如同在pre-receive
hook,接受签字推后。
使用这个hook,很容易生成描述存储库更新的邮件。此示例脚本每次发送一条邮件消息,列出推送到存储库的提交,并将具有良好签名的签名推送推送证书记录到记录器服务:
#!/bin/sh # mail out commit update information.while read oval nval refdo 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 anyif test -n "${GIT_PUSH_CERT-}" && test ${GIT_PUSH_CERT_STATUS} = Gthen ( 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。如果其他用户在更新后修改了ref git-receive-pack
,但在钩子能够评估之前,这很容易发生。建议钩子依赖于sha1-new而不是refname的当前值。
更新后的hook
经过所有其他处理后,如果至少更新了一个ref,并且$ GIT_DIR/hooks/post-update文件存在并且是可执行文件,则更新后将使用已更新的ref列表调用。这可以用来实现任何存储库范围的清理任务。
该hook调用的退出代码被忽略;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
钩子不得更新任何指向隔离对象的参考。访问存储库的其他程序将无法看到对象(并且如果预接收挂钩失败,则这些引用会损坏)。为了安全起见,任何来自内部的ref更新都会pre-receive
被自动拒绝
另请参阅
git-send-pack[1], gitnamespaces[7]