我的post-receive,一个git hook,有两个命令不起作用

时间:2017-12-23 19:27:06

标签: git githooks git-post-receive post-receive-email

我有三个git存储库:

  1. 我的git服务器上的裸存储库
  2. 我的笔记本电脑上的本地存储库(A)(我在这台机器上开发网页。)
  3. 托管服务器上的本地存储库(B)(我将其用作http服务器。)
  4. 我在裸存储库上设置了一个post-receive,一个服务器端钩子,让存储库(B)从裸机中拉出来,让git服务器在我提交并从存储库推送时发送通知邮件(A)到裸仓库。我在裸存储库上创建的收发后文件如下:

    #!/bin/sh
    ssh -l MYUSER -i PRIVKEY www.HOSTINGSERVER.com "cd GITDIRECTORY;git pull"
    . $(dirname $0)/post-receive-email
    

    我还在裸存储库中设置了环境变量:

    git config hooks.mailinglist "MyMailAddress"
    git config hooks.announcelist "MyMailAddress"
    git config hooks.emailprefix "FooBar"
    echo FooBar > description
    

    我预计存储库(B)被拉出,git服务器在我提交并推送到裸存储库时通过post-receive-email发送通知电子邮件,但是post-receive没有像我希望的那样工作。它有存储库(B)拉,但没有git服务器发送任何电子邮件。我没有在git服务器的日志中看到任何电子邮件错误。

    当我评论收到后的ssh部分时,我收到了一封电子邮件。当我注释掉收件后电子邮件部分时,存储库(B)正确拉出。当ssh部分和post-receive-email部分都处于活动状态时,post-receive只有存储库(B)拉,并且没有发送任何电子邮件。

    我不知道为什么当同时存在ssh部分和post-receive-email部分时,post-receive无法正常工作。

    任何提示和评论都表示赞赏。 提前谢谢。

1 个答案:

答案 0 :(得分:4)

TL; DR:ssh -n

背景事实:

  1. post-receive hook在其标准输入上获得输入。读取标准输入后,每个更新的参考文献将获得一行,格式为the githooks documentation

  2. 所有在stdin上接收输入的Git钩子都在管道上执行。 (我认为这是一个坏主意 - 他们应该在临时文件上接收他们作为文件描述符打开的输入 - 但这是一场单独的战斗。即使不是这种情况,你仍然需要另一个技巧。)

  3. 读取管道上可用的输入会消耗该输入。一旦阅读,它就消失了。

    (顺便说一句,这就是shell中内置read效率低的原因:必需一次读取一个字节的输入,所以只有就像消耗的read一样。)

  4. 考虑到这一点,请考虑ssh命令,以及documentation的摘录:

      

    -n / dev / null 重定向stdin(实际上,阻止从stdin读取)。

    那么,如果您在没有 ssh的情况下运行-n 会怎样?当然,它会读取标准输入。但是......它会怎样很多?好吧,严格来说,这取决于:ssh运行多个进程和/或线程,并且如果存在大量stdin输入并且远程端上运行的命令执行得非常快,则存在竞争,但通常, ssh读取是所有的标准输入。

    现在查阅背景事实#3,并回答问题:当ssh完成时,stdin上还剩下什么?

    现在,考虑一下发送电子邮件的post-receive挂钩。必须读取其标准输入以查看哪些引用已更新。它的stdin会得到什么数据?

    如果你阻止ssh读取(从而消耗)所有输入,那么后接收挂钩将能够读取(并消耗,但现在不再重要)所有输入,因此功能正常。