一种可能性是您的post-receive 挂钩:
然后你安装一个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-receive 或 update 钩子在新对象(提交、带注释的标签对象、树和 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
}
两步流程更容易。