【问题标题】:How to automatically update git hooks?如何自动更新 git 钩子?
【发布时间】:2016-02-28 16:49:07
【问题描述】:

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

我尝试了 3 件事,但都没有奏效。在接收后挂钩中,我

  1. 符号链接到 repo 中的文件
  2. 硬链接到 repo 中的文件
  3. 最后,将文件从 repo 复制到 hooks 目录中。

所以,我在我的存储库中保留了这个文件的副本,但我希望它能够自动部署。

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

有没有事实上的方法来做到这一点?

【问题讨论】:

    标签: git


    【解决方案1】:

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

    • 检测到post-receive 脚本是推送内容的一部分。
      (见“git post-receive hook to check files”:git diff --name-only $1..$2|grep post-receive
    • 复制到.git/hook/post-receive.new

    然后你安装一个pre-receive 钩子,它只检查.git/hook/post-receive.new 并将其重命名为.git/hook/post-receive
    (意思是 post-receive.new 消失,接下来的pre-receive 钩子执行什么都不做)

    这样,钩子不会立即更新,但会在下一次git push 更新到同一个仓库。


    注意:我想过在pre-receive钩子执行期间直接检测和更新post-receive文件修改,但是,正如“Git pre-receive hook to check config”中的torek所解释的,这并非易事:

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

    对于每个推送的 ref,您需要比较并检查该文件的存在和内容。
    也不是不可能,如seen in this php script

    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
    }
    

    两步流程更容易。

    【讨论】:

    • @cadegalt 不需要内部结构:您在git-scm.com/book/en/v2/… 有这些钩子的描述
    • @cadegalt 当然,这也可以工作,并且完全绕过 git。如果你是唯一一个推送到 git repo 托管服务器的人,这不会带来任何风险。
    • @cadegalt 不,它没有。 ssh 或 https。不是 scp (git-scm.com/book/ch4-1.html#The-SSH-Protocol)
    • 似乎很多人都想这样做,将其作为一个特性添加到 git 本身可能是最有效的方法。
    猜你喜欢
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 2012-06-03
    • 2011-05-17
    • 2018-10-15
    • 1970-01-01
    • 2019-07-20
    相关资源
    最近更新 更多