如何自动更新git hooks?

时间:2016-02-28 01:57:59

标签: git

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

我尝试了3件事,但都没有用。在收件后挂钩我

  1. 象征性地链接到repo中的文件
  2. 硬链接到repo中的文件
  3. 最后,将文件从repo复制到hooks目录。
  4. 所以,我在我的存储库中保留了这个文件的副本,但我希望它能自动部署。

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

    有没有这样做的方法?

1 个答案:

答案 0 :(得分:3)

一种可能性是你的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更新到同一个仓库。

注意:我考虑过在post-receive挂钩执行期间直接检测和更新pre-receive文件修改,但正如torekGit pre-receive hook to check config所解释的那样,并非无足轻重:

  

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

对于每个引用的引用,您需要进行区分并检查该文件的存在和内容 这不是不可能的,如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
}

进行两步操作更容易。