Git版本控制管理——钩子

Git中的钩子可以理解为一个特殊动作触发的脚本。

任何时候当版本库中出现如提交或补丁等特殊事件时,都会触发执行一个或多个任意的脚本。通常情况下,一个事件会分解为多个规定好的步骤,可以为每个步骤绑定自定义脚本。当Git事件发生时,每一步开始都会调用相应的脚本。

钩子只属于并作用于一个特定的版本库,在克隆操作中不会复制。换句话说,在私有版本库中设置的钩子不会传送到新克隆的版本库,也就不会改变新克隆的仓库的行为。而如果真的有需要的话,则需要获取被克隆版本库的.git/hooks目录。

一个钩子既可以在当前本地版本库的上下文中运行,也可以在远程版本库的上下文中运行。大多数Git钩子属于两类:

  • 前置(pre)钩子会在动作完成前调用。要在变更应用前进行批准,拒绝或者调整操作,可以使用前置钩子
  • 后置(post)钩子会在动作完成后调用,其可用于触发通知或者额外处理,如执行构建或关闭bug

通常情况下,如果前置钩子以非零状态推出,即异常,那么Git的动作会终止,而后置钩子的总是在Git操作后执行,因此其状态总是会被忽略。

从上面的描述来看,钩子的特性有:

  • 改变Git的行为
  • 拖慢原来的Git操作
  • 加快或拖慢工作效率,这取决于钩子本身的优劣
  • 版本库中的钩子不会自动复制

安装钩子

每个钩子简单地说都是一个脚本,作用于一个特定版本库的钩子集合都位于.git/hooks目录下。不过既然是脚本,就应该遵循UNIX脚本的基本规范,文件本身是可执行的和文件首行应指明脚本使用的语言。

每个钩子都是以它相关联的事件命名的。如在git commit操作之前执行的钩子称为.git/hooks/pre-commit。

钩子示例

在创建新的版本库时,钩子是自动复制自本地的Git模板目录的。比如Windows中的Git模板来自Git\mingw64\share\git-core\templates\hooks这个目录。绝大多数Git版本都包含用户可以使用的一些钩子,并会预装到模板目录下。

对于模板钩子来说:

  • 可能模板钩子并不能满足用户的需要
  • 尽管钩子是默认创建的,但初始时它们都是禁用的。根据具体的Git版本和操作系统的不同,钩子可以通过移除可执行位或在名字后添加.sample后缀来禁用
  • 而为了启用钩子,就需要移除.sample名称后缀,并设置可执行位

可用的钩子

可执行git help hooks查看Git当前版本总可用的钩子。

与提交相关的钩子

所有提交钩子都是为git commit服务的,但git rebase/git merge/git am都默认不执行提交钩子,然后git commit --amend会执行提交钩子。

当执行git commit时,Git会执行上图的过程:

  •  在提交内容发生错误时,pre-commit钩子能够使该提交被放弃。因为pre-commit钩子会在用户能够编辑提交信息前执行,因此用户不会在输入了提交消息之后才发现被拒绝了。还可以使用该钩子自动修改提交内容。
  • pre-commit-msg钩子能够让用户在Git的默认消息展示给用户前做出修改。比如,可以使用其来修改默认的提交消息模板
  • commit-msg钩子能在用户编辑后验证或修改提交信息。比如拼写检查等
  • post-commit钩子在提交操作结束后执行。比如可以更新日志,发送通知邮件等

与补丁相关的例子

 当执行git am时,Git会执行上图的过程:

  • applypatch-msg会检查补丁中的提交消息并决定其是否是可接受的。比如根据补丁内容确定是否要接受该补丁
  • pre-applypatch钩子在应用补丁之后,提交结果之前执行的
  • post-applypatch和post-commit脚本类似

与推送相关的钩子

 当执行git push时,Git的接收端会执行上图的过程。

所有与推送相关的狗子都在接收端执行,而不是发送端。因此,执行的钩子脚本是在接收端的.git/hooks目录下运行,而不是在发送端。远程钩子的输出结果会显示给执行git push的用户。

而git push的第一步是将本地版本库中所有缺少的对象传输到远程版本库中,此时不需要钩子,因为所有的Git对象都是通过散列值标识的,而钩子不能改变对象。

而除了操作对象本身之外,与推送相关的钩子在需要更新引用时也会调用。

  • pre-receive会接收所有需要更新的引用列表,包括其新旧对象指针。该钩子可以确认接受或拒绝所有变更
  • update钩子只在每个引用更新的时候调用一次。该钩子可以选择接受或拒绝单个分支的更新,而不影响其它分支是否更新。而对于每次更新,用户都能触发一个动作,比如发送邮件确认
  • post-receive钩子也会接收所有刚更新的引用列表。
  • post-update钩子已经被新的post-receive钩子替代了。

其它钩子

  • pre-rebase钩子在需要变基一个分支时调用,因此其能避免在不应该变基的分支上意外执行git rebase。
  • post-checkout钩子在切换分支或检出分支后调用,比如创建目录,检查检出文件的权限信息等
  • post-merge钩子在执行合并后调用
  • pre-auto-gc钩子可以帮助git gc --auto决定是否需要清理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值