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