前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >git hook实践心得

git hook实践心得

作者头像
IMWeb前端团队
发布2019-12-03 16:38:31
1.2K0
发布2019-12-03 16:38:31
举报
文章被收录于专栏:IMWeb前端团队

本文作者:IMWeb 何璇 原文出处:IMWeb社区 未经同意,禁止转载

优秀的团队必不可缺少源代码的质量管理,比如eslint、sasslint等代码检测工具,借助git hook能力,我们可以将这些工具无缝地整合到git开发工作流中。

git hook介绍

Like many other Version Control Systems, Git has a way to fire off custom scripts when certain important actions occur

Git hook能够在发生某特定行为的时机,触发执行自定义的脚本。

git hook分类

Git hook分为客户端hooks(Client-Side Hooks)和服务端hooks(Server-Side Hooks),下面列出了所有可以触发hook的时机,可以在官方文档中查询:

  • Client-Side Hooks
    • pre-commit: 执行git commit命令时触发,常用于检查代码风格
    • prepare-commit-msg: commit message编辑器呼起前default commit message创建后触发,常用于生成默认的标准化的提交说明
    • commit-msg: 开发者编写完并确认commit message后触发,常用于校验提交说明是否标准
    • post-commit: 整个git commit完成后触发,常用于邮件通知、提醒
    • applypatch-msg: 执行git am命令时触发,常用于检查命令提取出来的提交信息是否符合特定格式
    • pre-applypatch: git am提取出补丁并应用于当前分支后,准备提交前触发,常用于执行测试用例或检查缓冲区代码
    • post-applypatch: git am提交后触发,常用于通知、或补丁邮件回复(此钩子不能停止git am过程)
    • pre-rebase: 执行git rebase命令时触发
    • post-rewrite: 执行会替换commit的命令时触发,比如git rebasegit commit --amend
    • post-checkout: 执行git checkout命令成功后触发,可用于生成特定文档,处理大二进制文件等
    • post-merge: 成功完成一次 merge行为后触发
    • pre-push: 执行git push命令时触发,可用于执行测试用例
    • pre-auto-gc: 执行垃圾回收前触发
  • Server-Side Hooks
    • pre-receive: 当服务端收到一个push操作请求时触发,可用于检测push的内容
    • update: 与pre-receive相似,但当一次push想更新多个分支时,pre-receive只执行一次,而此钩子会为每一分支都执行一次
    • post-receive: 当整个push操作完成时触发,常用于服务侧同步、通知

如何使用git hook

hook脚本会存放在仓库.git/hooks文件夹中,git提供了一些shell样例脚本以作参考。

pre-push.sample:

代码语言:javascript
复制
#!/bin/sh

# An example hook script to verify what is about to be pushed.  Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed.  If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
#   <local ref> <local sha1> <remote ref> <remote sha1>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).

remote="$1"
url="$2"

z40=0000000000000000000000000000000000000000

while read local_ref local_sha remote_ref remote_sha
do
    if [ "$local_sha" = $z40 ]
    then
        # Handle delete
        :
    else
        if [ "$remote_sha" = $z40 ]
        then
            # New branch, examine all commits
            range="$local_sha"
        else
            # Update to existing branch, examine new commits
            range="$remote_sha..$local_sha"
        fi

        # Check for WIP commit
        commit=`git rev-list -n 1 --grep '^WIP' "$range"`
        if [ -n "$commit" ]
        then
            echo >&2 "Found WIP commit in $local_ref, not pushing"
            exit 1
        fi
    fi
done

exit 0

你只需要在.git/hooks文件夹中新建以钩子名命令的脚本文件(比如pre-push),这个脚本就会在适当的时机被触发。

一些实践

husky

husky是用node实现的一个快速安装git hooks的工具,在项目中安装后,就可以在package.json中指定相关钩子执行的npm scripts。

代码语言:javascript
复制
// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "npm test",
      "pre-push": "npm test",
      "...": "..."
    }
  }
}

但它存在一些些限制,后续说明。

imlint

imlint是团队正在使用的一款git hook工作流生成工具,可以快速方便地实现eslintsasslint等校验能力。

interactive hook

近期想在husky的基础上实现询问用户输入的hook,代码如下:

代码语言:javascript
复制
console.log(`\n确认执行命令\n${question}?(y/n)`));
process.stdin.on('data', (data) => {
  // do something...
});

但是git hook进程完全不管你是否在等待用户输入,直接就退出了,继续执行了相关操作。Google后发现,原来git hook被设计为不可交互的行为。

非要询问用户输入,可以监听非标准输入/dev/tty,代码如下:

代码语言:javascript
复制
# ...
exec < /dev/tty
# ...
代码语言:javascript
复制
if (process.platform === 'win32') {
  // husky不支持配置.git/hooks/xx 中的sh脚本
  // 需要手动加入 exec < /dev/tty 开启交互
  stream = process.stdin;
} else {
  stream = fs.createReadStream('/dev/tty');
}

stream.setEncoding('utf-8');
stream.on('error', () => {
  // do something...
});
stream.on('data', (data) => {
  // do something...
});

windows系统的兼容问题,请参考

https://nodejs.org/docs/latest-v8.x/api/tty.html

Reference

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-06-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • git hook介绍
    • git hook分类
      • 如何使用git hook
      • 一些实践
        • husky
          • imlint
            • interactive hook
            • Reference
            相关产品与服务
            检测工具
            域名服务检测工具(Detection Tools)提供了全面的智能化域名诊断,包括Whois、DNS生效等特性检测,同时提供SSL证书相关特性检测,保障您的域名和网站健康。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档