git安装配置-一个 git 仓库下拥有多个项目的 git hooks 配置方案

生活百科1年前 (2023)发布 aixure
82 0 0

前言

通常情况下,一个 git 仓库就是一个项目,只需要配置一套 git hooks 脚本就可以执行各种校验任务。对于 monorepo 项目也是如此,monorepo 项目下的多个 packages 之间,它们是有关联的,可以互相引用,所以当成一个项目也没问题。

但是也有一种情况,一个 git 仓库下的多个项目之间是彼此独立的,比如 git 仓库下存在前端项目、后端项目、文档项目等等。这时候就需要为每个项目配置不同的 git hooks 脚本git安装配置,因为不同的项目有可能校验规则不一样。

本文主要探讨一下如何为不同的项目配置 git hooks 脚本。

PS:配置 git hooks 脚本使用huksy[1]。

方案一:每个项目下都配置一套 git hooks 脚本

git安装配置-一个 git 仓库下拥有多个项目的 git hooks 配置方案

假设仓库拥前后端两个项目:

frontendbackend

那么我们需要在每个项目下安装husky,同时要在package.json中配置一下prepare脚本(这里以前端项目为示例):

# package.json{    "scripts" {        "prepare": "cd .. && husky install frontend/.husky"    }}

然后按照husky文档创建pre-commit和commit-msg钩子文件:

git安装配置-一个 git 仓库下拥有多个项目的 git hooks 配置方案

#!/usr/bin/env sh. "$(dirname -- "$0")/_/husky.sh"
# pre-commitcd frontendnpx lint-staged

#!/usr/bin/env sh. "$(dirname -- "$0")/_/husky.sh"
# commit-msgcd frontendFORCE_COLOR=1 node scripts/verifyCommitMsg.mjs $1

上面展示的是前端项目的 git hooks 创建过程,后端项目按照同样的过程创建即可。目前仓库的目录结构如下:

frontend    .husky        - pre-commit        - commit-msgbackend    .husky        - pre-commit        - commit-msg

运行一段时间后,发现这个方案有问题,那就是每次触发的 git hooks 脚本都是前端项目的,后端项目提交代码根本不触发 git hooks。排查问题后发现是 git 仓库的配置引起的git安装配置,打开.git/config文件:

[core]    hooksPath = frontend/.husky

上面hooksPath路径对应的就是 git hooks 的目录位置,目前 git 只支持指定一个目录作为 git hooks 的位置。所以第一个方案不靠谱,达不到我们想要的效果。

方案二:只在根目录下配置一套 git hooks 脚本

第二个方案是将 git hooks 放在项目根目录下,统一在根目录里执行各个子项目的校验脚本。这个方案有以下几个步骤:

修改 husky 安装位置

在每个项目下安装 husky 时,要把 git hooks 钩子目录设置在根目录:

# package.json{    "scripts" {        "prepare": "cd .. && husky install .husky" # 放到根目录    }}

同时.git/config文件也要修改一下:

[core]    hooksPath = .husky # 改为根目录

在 git hooks 中进行各个子项目的校验操作

git安装配置-一个 git 仓库下拥有多个项目的 git hooks 配置方案

这里以commit-msg作为示例编写一个脚本:

#!/usr/bin/env sh. "$(dirname -- "$0")/_/husky.sh"
# 拿到所有改动的文件名changedFiles=$(git diff --cached --name-only --diff-filter=ACM)
# 判断目录是否改动isBackendChanged=falseisFrontendChanged=false
for file in $changedFilesdo if [[ $file == frontend/* ]] then isFrontendChanged=true elif [[ $file == backend/* ]] then isBackendChanged=true fidone
# 改动的目录需要执行校验命令# $1 $2 代表传给函数的第一个、第二个参数execTask() { echo "root $1 commit-msg" cd $1 FORCE_COLOR=1 node scripts/verifyCommitMsg.mjs $2}
if $isFrontendChangedthen execTask "frontend" $1 & # 使用 & 让任务在后台执行 task1=$! # 保存任务 idfi
if $isBackendChangedthen execTask "backend" $1 & task2=$!fi
if [[ -n $task1 ]]; then wait $task1fi
if [[ -n $task2 ]]; then wait $task2fi
echo "All tasks finished."

上面脚本的逻辑是这样的:

1.每次 git 提交代码时,判断一下当前所有改动的文件是属于哪个项目2.文件发生改动的项目需要执行校验任务3.每个校验任务都使用子进程去执行4.等待所有校验任务执行结束后,输出All tasks finished.

测试一段时间后,发现第二个方案没发生什么问题,完全满足需求。

References

[1]huksy:

限时特惠:本站每日持续更新海量各大内部网赚创业教程,会员可以下载全站资源点击查看详情
站长微信:
git安装配置-一个 git 仓库下拥有多个项目的 git hooks 配置方案

© 版权声明

相关文章

暂无评论

暂无评论...