如何自动更新git挂钩?

如何自动更新git挂钩?,git,Git,所以,我唯一使用的钩子是post-receive。当我在我的客户机上编辑此文件时,我希望它在推送到服务器时自动更新 我尝试了三种方法,但都不起作用。在邮局我收到了钩子 以符号方式链接到回购协议中的文件 硬链接到回购协议中的文件 最后,将文件从repo复制到hooks目录中 因此,我在我的存储库中保留了该文件的一个副本,但我希望它能够自动部署 我认为我尝试的方法的主要问题是,当我尝试更新文件时,文件正在被使用,也就是说,它在自己作用 有什么实际的方法可以做到这一点吗?一种可能是让您的post re

所以,我唯一使用的钩子是post-receive。当我在我的客户机上编辑此文件时,我希望它在推送到服务器时自动更新

我尝试了三种方法,但都不起作用。在邮局我收到了钩子

  • 以符号方式链接到回购协议中的文件
  • 硬链接到回购协议中的文件
  • 最后,将文件从repo复制到hooks目录中
  • 因此,我在我的存储库中保留了该文件的一个副本,但我希望它能够自动部署

    我认为我尝试的方法的主要问题是,当我尝试更新文件时,文件正在被使用,也就是说,它在自己作用


    有什么实际的方法可以做到这一点吗?

    一种可能是让您的
    post receive
    挂钩:

    • 检测
      post receive
      脚本是否是推送内容的一部分。
      (请参阅“”:
      git diff--name only$1..$2 | grep post receive
    • .git/hook/post receive.new中复制一份
    然后安装一个
    pre-receive
    hook,只需检查
    .git/hook/post-receive.new
    并将其重命名为
    .git/hook/post-receive

    (意味着post-receive.new消失,下一次
    pre-receive
    hook执行将不起任何作用)

    这样,钩子不会立即更新,但它将在下一次推送到同一回购时更新


    注意:我考虑过在
    预接收
    钩子执行期间直接检测和更新
    接收后
    文件修改,但是,正如在“”中所解释的,这并不是一件小事:

    在将新对象(提交、带注释的标记对象、树和blob)加载到存储库之后,但在更改引用(分支名称、标记名称等)之前,将调用
    pre-receive
    update
    钩子

    对于每个推送的ref,您需要区分并检查该文件的存在和内容。
    这并非不可能,因为:


    两步流程更容易。

    @cadegalt不需要内部:您在@cadegalt上有关于这些钩子的描述,当然,这也可以工作,并且完全绕过git。如果你是唯一一个推到git repo托管服务器的人,这不会带来任何风险。@cadegalt不,不会。ssh或https。不是scp(),似乎很多人都想这样做,在git中添加这个特性可能是最有效的方法。
    function get_changed_files($base, $commit) {
      list($code, $stdout, $stderr) = git('diff', '--numstat', '--name-only', '--diff-filter=ACMRTUXB', '--ignore-submodules', "{$base}..{$commit}");
      ...
      return explode("\n", $stdout);
    }
    function get_new_file($filename, $commit) {
      list($code, $stdout, $stderr) = git('show', "{$commit}:{$filename}");
      ...
      return $stdout;
    }
    ...
    $line = file_get_contents('php://stdin');
    list($base, $commit, $ref) = explode(" ", trim($line));
    if ($base == "0000000000000000000000000000000000000000") {
      verbose("Initial push received. Expecting everything to be fine");
      exit;
    }
    $modified = get_changed_files($base, $commit);
    $result = true;
    foreach ($modified as $fname) {
      // if fname equals post-receive
      $contents = get_new_file($fname, $commit);
      // copy it to .git/hooks/post-receive
    }