git hook

这篇具有很好参考价值的文章主要介绍了git hook。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

hook

hook 翻译为钩子,简单说就是监听某个事件(操作),然后触发自定义逻辑
在 git 中可以监听 commit,push 等操作,在操作之前或之后触发对应的 hook,在 hook 中写自定义的逻辑,比如在提交之前做一些检查,检查未通过不允许提交

下面这些是 git hook 触发的时机

git hook,git,git
其中蓝色方块是某些操作之后触发,它不会阻塞操作,就是执行一些额外的操作
黄色和红色方块是某些操作之前触发,可以做一些检查,不满足条件会阻塞操作,区别在于黄色方块的操作可以跳过

克隆一个仓库并显示隐藏的文件,可以看到仓库根目录下的 .git 文件夹中有提供了一些 hook 例子,这些 hook 默认不生效,去掉 .sample 后缀才会生效
git hook,git,git
这些 hook 都是用 shell 命令编写的,查看 pre-commit

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	against=$(git hash-object -t tree /dev/null)
fi

allownonascii=$(git config --type=bool hooks.allownonascii)

exec 1>&2

if [ "$allownonascii" != "true" ] &&
	test $(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
	cat <<\EOF
Error: Attempt to add a non-ASCII file name.
This can cause problems if you want to work with people on other platforms.
To be portable it is advisable to rename the file.
If you know what you are doing you can disable this check using:
  git config hooks.allownonascii true
EOF
	exit 1
fi

exec git diff-index --check --cached $against --

它会检查提交的文件名里是否有非 ASCII 码,exit 1 表示检查没有通过,exit 0 表示检查通过
这些 hook 我们可以修改逻辑,但是它只会在本地生效,因为 .git 文件夹里的修改不会上传到仓库,为了参与项目的人都能使用 hook,需要借助第三方工具来实现

commitlint + husky

首选需要安装 node.js,官网下载安装即可
在项目根目录安装

npm install --save-dev @commitlint/cli @commitlint/config-conventional

安装 commitlint/cli 和 commitlint/config-conventional 这两个包,并将其添加到 devDependencies(开发阶段的依赖,就是我们在开发过程中需要用的依赖,只在开发阶段起作用的),并将该信息保存到 package.json中

commitlint/cli 是一个命令行工具,用于校验 Git 提交信息的格式是否符合规范。
commitlint/config-conventional 是一个常用的配置文件,它定义了一些常见的 Git 提交信息规范,例如 Angular 的规范。它包含了一些预定义的规则,可以直接使用,也支持自定义规则

新建 commitlint.config.js 文件,增加配置项

module.exports = {
  // 继承的规则
  extends: ['@commitlint/config-conventional'],
  // 定义规则类型
  rules: {
    // type 类型定义,表示 git 提交的 type 必须在以下类型范围内
    'type-enum': [
      2,
      'always',
      [
        'feat', // 新功能 feature
        'fix', // 修复 bug
        'docs', // 文档注释
        'style', // 代码格式(不影响代码运行的变动)
        'refactor', // 重构(既不增加新功能,也不是修复bug)
        'perf', // 性能优化
        'test', // 增加测试
        'chore', // 构建过程或辅助工具的变动
        'revert', // 回退
        'build' // 打包
      ]
    ],
    // subject 大小写不做校验
    'subject-case': [0]
  }
}

rule由name和配置数组组成,如上面的:‘type-enum:[2, ‘always’, […]]’,数组中第一位为level,可选0,1,2,0为disable,1为warning,2为error,这里的 2 表示错误级别,表示如果提交消息不符合规则,将会以错误级别报错,第二位为应用与否,可选 always|never,always 表示规则必须被应用到每一个提交消息中,第三位该rule的值,这里定义了 git 提交的类型,提交信息的开头必须是上面定义的类型,如

fix: 修复了某个bug

安装 husky

npm install husky --save-dev

在 package.json 中添加 prepare 脚本并运行,创建 .husky 文件夹

npm pkg set scripts.prepare="husky install"
npm run prepare

将一个名为 pre-commit 的 git hook 添加到 .husky 目录中

npx husky add .husky/pre-commit "npm test"

这里的 “npm test” 是 hook 中的指令,生成后可以随意修改,比如检查文件的名称,路径是否合法

添加一个 commit-msg 钩子,它会在每次提交代码时运行 commitlint,以确保提交的消息符合规范

npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

修改文件做测试
git hook,git,git
提交信息的开头包含必须是配置中定义的类型(feat,fix等)才能提交

git hook,git,git
最后把生成的这些文件提交到仓库,参与项目的人提交时都会受到在 hook 中做检查

使用 hook 实现主仓库和子模块的联动操作

子模块

子模块相当于子仓库,就是把一个 git 仓库作为另一个 git 仓库的子仓库

git submodule add https://gitee.com/xxx/sub1.git

在仓库下执行 git submodule add url(仓库地址),就会添加一个子模块,这时会生成 .gitmodules 和 一个子模块的文件夹,.gitmodules 中记录子模块的路径和仓库地址

[submodule "sub1"]
	path = sub1
	url = https://gitee.com/xxx/sub1.git

初始化所有的子仓库并更新

git submodule update --init --recursive

修改提交后,在主仓库可以看到子模块后面有个commit hash 值,这对应子模块的某一个版本
git hook,git,git
当我们克隆一个包含子模块的仓库时,它默认是不生成子模块的内容,需要递归的方式克隆整个项目才行

git clone url --recursive

或者克隆的时候勾选 Recursive

git hook,git,git

联动

为了让主仓库更新时,子模块也更新,在 .husky 文件夹下添加 post-merge 这个 hook,使用 git pull 更新后会触发 post-merge,因为 git pull 就是 git fetch 和 git merge 的简写,在 post-merge 里更新子模块

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# git pull 触发 merge 操作,更新所有子仓库
git submodule foreach 'git pull'

exit 0

如果子模块有更新,主仓库没有更新,此时执行 git pull 不会触发 post-merge,因为没有发生 merge 操作

如果需要主仓库切分支时,子模块也切分支,需要添加 post-checkout 这个 hook。
在执行 git clone 和 git checkout 后会触发 post-checkout,在克隆仓库或切分支后,会检查是否有子模块,有就初始化子模块,主仓库切分支后,如果这个分支名称是dev开头,子模块也会切过去

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

## $1是HEAD的前一个SHA值,$2是HEAD的当前SHA值。如果$1和$2相同,表示没有切换分支
if [ "$1" = "$2" ]; then
  exit 0
fi

# git clone 也会触发 post-checkout
# 存在子模块且未初始化,则初始化并更新
if [ -f .gitmodules ]; then
  if git submodule status | grep -q '^[-]'; then
    git submodule update --init --recursive --remote --merge
  fi
else
  exit 0
fi

branch=$(git branch --show-current)
#echo "branch-name: $branch"
# branch为空跳过
if [ -z "$branch" ]; then
  exit 0
fi

#如果分支名以dev开头,子模块也切过去,没有对应分支则创建分支并切过去
if [[ $branch == dev* ]]; then
  git submodule foreach "git checkout -b $branch || git checkout $branch"
fi

exit 0

检查脚本的编码格式

有的人脚本使用非utf-8编码,这样别人看他中文注释就会乱码,针对这个问题,我们可以在提交时检测下脚本的编码方式
在 .husky 文件夹下添加 pre-commit 这个 hook

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 获取所有要提交的文件
filePaths=`git diff --cached --name-only`
# 定义数组存放有问题的文件
error=( )
# 遍历提交文件,检查脚本编码
for path in ${filePaths};
do
  # echo $path
  # 检查脚本编码是否为 utf-8 或 utf-8—bom,us-ascii 是 utf-8 的子集
  if [[ $path == "Assets/"* ]] && [[ ${path##*.} == "cs" ]]; then
    format=$(file -b --mime-encoding $path)
    echo $format
    if [[ $format != utf-8* ]] && [[ $format != us-ascii ]]; then
        error[${#error[*]}]="${path}"
    fi
  fi
done
# 输出
if [ "$error" = "" ]; then
  echo "检测通过"
  exit 0
else
  echo "检测失败,脚本编码必须是 utf-8 或者 utf-8-bom"
  for var in ${error[@]}
  do 
    echo $var
  done
  exit 1
fi

参考

git hook文章来源地址https://www.toymoban.com/news/detail-581830.html

到了这里,关于git hook的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • git 提交代码 出现的错误 pre-receive hook declined

    错误提示: 问题定位: 原因是由于没有提交到master 的权限,既然定位到问题了,那么就好办,权限不足就配置权限得了呗。 解决方案: 打开网页版本,进入项目,点击 SettingsMembers,进行人员权限配置 权限配置后再次push就成功了

    2024年02月11日
    浏览(57)
  • .git/hooks/pre-commit: line XXX: node: command not found git报错

    在Mac下使用sourcetree提交代码,出现如下报错: 使用诸如SourceTree这样的gui,可以访问的环境变量不一样,需要在.git/hooks/pre-commit脚本中加入你的node环境变量 首先打印你的node目录: 比如(每个人的目录都不同) 然后将目录加入到 你的git项目下 .git/hooks/pre-commit 中

    2024年02月12日
    浏览(47)
  • 【问题记录】git报错:[remote rejected] (pre-receive hook declined)

    经过排查,不是因为权限不足,是由于commit提交不规范引起的提交失败,报错如下 修改commit信息,用下面这行命令就行 然后重新push,就成功了

    2024年02月12日
    浏览(47)
  • git commit报错:running pre-commit hook: lint-staged

    running pre-commit hook: lint-staged 在项目(vue)的package.json文件中,查找 “husky” 部分,并确认其下的 “pre-commit” 钩子是否正确地引用了 lint-staged。 其中配置示例如下 (供参考,不会配的话粘过去就能用): 希望记录的问题,能够帮助到你!

    2024年02月05日
    浏览(35)
  • git提交失败之running pre-commit hook: lint-staged

    在项目中提交代码时遇到了git报错,但是很疑惑不知道为什么报错。上网差了查才发现是项目中有语法校验,在提交中git默认不允许存在很多语法错误的文件提交。 错误提示: git:running pre-commit hook:lint-staged 错误分析: 错误的意思是大概是有一个钩子,提交前检查项目代码的

    2024年02月13日
    浏览(38)
  • 【Git】Git commit至Gitee报错‘remote: error: hook declined to update refs/heads/master‘的解决方法

    Git commit至Gitee报错‘remote: error: hook declined to update refs/heads/master‘的解决方法 进入到Gitee的 邮箱管理 中,取消勾选 禁止命令行推送暴露个人邮箱

    2024年02月04日
    浏览(37)
  • git提交终端报husky - pre-commit hook exited with code 1 (error)

    今天像往常一样正常提交代码不知道哪里出了问题 终端“抽风”了 我没提交成功 报错如下 然后就开始找解决方法 看到最多的是commit时加上提交信息 :\\\"fix:xxxx\\\" 然后我就试了一下 发现并没有用 欸 咋整捏 (ps: 这个方法我用了之后没用 不代表他就是错的呀 可能是错误不太一样

    2024年02月11日
    浏览(43)
  • git push解决办法: ! [remote rejected] master -> master (pre-receive hook declined)

    项目经理远程创建了一个 空项目 ,无任何内容,给我赋予的 developer 账号权限,本地改为后提交代码试了很多次都上传不上去,报错如下: 先说结果: git push 不上去的原因在于所push的 分支权限 为 protected, 只有项目的 管理员 或具有相应权限的人才能进行 push ,要进行项目的

    2023年04月25日
    浏览(31)
  • git提交时报错:husky-commit-msg hook exited with code 1 (error)

    ​问题描述: git commit 时控制台报错: 由于项目使用了husky,在提交前对代码规范进行了校验,导致报错 这种情况下无法直接push o(╥﹏╥)o ​ 解决方案: commit 时加上提交信息:“fix: xxxxx”,比如: 提交后就可以顺利push了 O(∩_∩)O ​

    2024年02月11日
    浏览(37)
  • git提交报错:husky - pre-commit hook exited with code 1 (error)

    提交代码的时候,提交错误了… 无论是使用 idea 自带的工具还是直接使用命令行都会报错 很明显报错信息: husky - pre-commit hook exited with code 1 (error) 部分人可以成功(我就不行…) 由于项目使用了husky,在提交前对代码规范进行了校验,导致报错

    2024年02月11日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包