尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
lefthook 的 source_dir 配置详解:自定义脚本存放目录的完整指南
lefthook 的 source_dir 配置详解自定义脚本存放目录的完整指南【免费下载链接】lefthookFast and powerful Git hooks manager for any type of projects.项目地址: https://gitcode.com/GitHub_Trending/le/lefthooksource_dir是 lefthook 中控制脚本scripts存放位置的核心配置项默认值为.lefthook/。本指南围绕 docs/configuration/source_dir.md 展开结合仓库源码说明其默认行为、目录约定、配置方法与底层解析逻辑帮助你彻底掌握脚本文件该放在哪、为什么放在哪、如何按需修改这一 lefthook 使用中的基础问题。一、source_dir是什么在 lefthook 中除了在lefthook.yml里直接通过commands内联命令外还可以把可执行脚本scripts放在独立目录中由 lefthook 在触发对应 Git hook 时负责查找并执行。source_dir就是用来改变这个脚本存放目录的顶层配置项。按照官方文档的定义Change a directory for script files. The directory contains subfolders named after git hooks, each containing script files.即source_dir指定脚本文件的根目录该目录下的子文件夹以 Git hook 名称命名每个子文件夹中再存放对应 hook 要执行的脚本文件。默认值source_dir默认值.lefthook/source_dir_local默认值.lefthook-local/见 docs/configuration/source_dir_local.md默认目录结构如下.lefthook/ ├── pre-commit/ │ ├── lint.sh │ └── test.py └── pre-push/ └── check-files.rb这意味着pre-commithook 会去.lefthook/pre-commit/下寻找配置中声明的脚本pre-pushhook 则会去.lefthook/pre-push/下寻找依此类推。二、脚本与source_dir的配合方式source_dir不是孤立存在的它服务于 lefthook 的Scripts机制。完整流程参见 docs/configuration/Scripts.md在lefthook.yml的某个 hook 下声明scripts条目键名即脚本文件名把实际脚本文件放入source_dir/hook-name/目录触发该 hook 时lefthook 会在项目根目录下定位并执行这些脚本。一个最小示例脚本放在默认目录.lefthook/pre-commit/# lefthook.yml pre-commit: scripts: my-script.sh: runner: bash文件布局.lefthook/ └── pre-commit/ └── my-script.sh也可以使用lefthook add命令快速搭建目录骨架lefthook add -d pre-commit该命令会检查 hook 名称是否合法参考 internal/config/available_hooks.go 中的AvailableHooks列表并在传入-d时同时创建全局与本地两个 source 目录下的对应 hook 子目录逻辑见 internal/command/add.go。三、如何自定义source_dir在lefthook.yml顶层添加source_dir键即可# lefthook.yml source_dir: .my-hooks/ pre-commit: scripts: my-script.sh: runner: bash此时脚本应放在.my-hooks/ └── pre-commit/ └── my-script.sh若使用本地配置lefthook-local.yml不入库的个人配置还可配合source_dir_local单独指定本地脚本目录# lefthook-local.yml source_dir_local: .lefthook-local/这种全局脚本 本地脚本的双目录设计正是 lefthook 支持本地化、个人化脚本如仅本机需要的格式化工具的基础详见 docs/configuration/source_dir_local.md。四、源码视角source_dir如何被解析和使用1. 配置字段与默认值定义source_dir对应 internal/config/config.go 中的Config.SourceDir字段其 JSON Schema 注解明确给出默认值.lefthook/与用途说明SourceDir string json:source_dir,omitempty jsonschema:default.lefthook/,descriptionChange a directory for script files. Directory for script files contains folders with git hook names which contain script files. koanf:source_dir mapstructure:source_dir,omitempty实际的默认值常量定义在 internal/config/loader.goconst ( DefaultConfigName lefthook.yml DefaultSourceDir .lefthook DefaultSourceDirLocal .lefthook-local )并且在配置反序列化阶段internal/config/loader.go会先为SourceDir、SourceDirLocal赋上默认值再通过unmarshalConfigs用实际配置文件覆盖config.SourceDir DefaultSourceDir config.SourceDirLocal DefaultSourceDirLocal因此即使lefthook.yml中不写source_dir其行为也是确定的脚本统一从.lefthook/下按 hook 名子目录查找。2. 运行期SourceDirs 列表的组装当执行某个 hook 时internal/command/run.go 中的getSourceDirs会依据配置组装一份查找目录列表func getSourceDirs(repo *git.Repo, cfg *config.Config) []string { sourceDirs : []string{ filepath.Join(repo.RootPath, cfg.SourceDir), filepath.Join(repo.RootPath, cfg.SourceDirLocal), // Additional source dirs to support .config/ filepath.Join(repo.RootPath, .config, lefthook), filepath.Join(repo.RootPath, .config, lefthook-local), } for _, remote : range cfg.Remotes { if remote.Configured() { // Append only source_dir, because source_dir_local doesnt make sense sourceDirs append( sourceDirs, filepath.Join(repo.RootPath, .., remote.SourceDir), ) } } return sourceDirs }从源码结构看脚本查找存在优先级与回退机制首先是自定义或默认的source_dir与source_dir_local其次兼容.config/lefthook与.config/lefthook-local对应 XDG 风格目录若配置了remotes远程共享配置还会追加远程配置声明的 source 目录远程场景下只追加source_dir因为source_dir_local对远程共享无意义。3. 脚本路径拼接与执行真正拼接脚本路径的逻辑在 internal/run/controller/command/build_script.go。buildScript会遍历上述SourceDirs对每个目录按filepath.Join(sourceDir, hookName, scriptName)拼出候选路径并逐一探测for _, sourceDir : range b.opts.SourceDirs { scriptPath : filepath.Join(sourceDir, b.opts.HookName, params.Script) fileInfo, err : b.git.Fs.Stat(scriptPath) if os.IsNotExist(err) { b.logger.Debugf([lefthook] script doesnt exist: %s, scriptPath) continue } ... }同时该函数还做了几件关键工作校验文件类型非普通文件如目录会被跳过并返回SkipError自动赋予执行权限若脚本缺少可执行位会以0o751权限自动Chmod保证脚本可直接运行拼接运行命令若声明了runner如bash则按runner scriptPath组织命令未声明 runner 时直接执行脚本本身并追加 Git 传入的参数若所有目录都找不到该脚本返回scriptNotExistsErrorscript does not exist: ...来中断该 job。这也解释了为什么脚本路径必须遵循source_dir/hook-name/script-name的约定——这个拼接是源码层面写死的。4. 配置转储时的省略规则在lefthook dump输出配置时internal/config/config.go 会做一项优化当SourceDir仍为默认值.lefthook时直接从输出中删除该字段避免冗余if c.SourceDir DefaultSourceDir { delete(res, source_dir) } if c.SourceDirLocal DefaultSourceDirLocal { delete(res, source_dir_local) }因此 dump 结果中只有显式自定义过source_dir的配置才会出现该键。五、source_dirvssource_dir_local两者同属脚本目录类配置但定位不同配置项默认值用途是否入库source_dir.lefthook/项目共享脚本目录通常随项目提交VCSsource_dir_local.lefthook-local/本地私有脚本目录不入 VCS通常由.gitignore排除典型场景团队共享的检查脚本放入.lefthook/随仓库分发而个人偏好如本地专用格式化脚本放入.lefthook-local/配合lefthook-local.yml使用互不干扰。运行期两者都会被并入SourceDirs查找列表因此同一 hook 下共享脚本与本地脚本可以同时生效。六、常见实践建议保持默认目录减少心智负担lefthook add、lefthook install、lefthook dump等命令均默认感知.lefthook/非必要不建议改动。自定义时注意相对路径source_dir是相对于项目根目录解析的见 internal/command/run.go 中filepath.Join(repo.RootPath, ...)请勿写成绝对路径或带../的越级路径。脚本命名与配置键名保持一致配置中scripts下的键必须与source_dir/hook/下的实际文件名完全一致否则会得到 script does not exist 错误。脚本需要可执行权限虽然 lefthook 会自动补权限0o751但建议在提交前就chmod x并确认 shebang 正确以保证在未触发自动修复的情况下也能稳定运行。远程共享配置的场景当通过remotes引入共享配置时脚本查找会额外追加远程声明的source_dir此时需保证该目录在共享仓库中真实存在。七、总结source_dir虽只是一个顶层配置键但它定义了 lefthook 脚本体系的目录约定source_dir/hook-name/script-file。从 internal/config/loader.go 的默认值注入到 internal/command/run.go 的多目录查找列表组装再到 internal/run/controller/command/build_script.go 的路径拼接与权限兜底整条链路共同保证了声明式配置 约定式目录这一简洁模型的稳定运行。理解它你就能灵活地组织项目脚本也能更好地掌握 Scripts、source_dir_local 以及 remotes 等关联配置。【免费下载链接】lefthookFast and powerful Git hooks manager for any type of projects.项目地址: https://gitcode.com/GitHub_Trending/le/lefthook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Linux atime、mtime、ctime 三时间戳详解与实战避坑

Linux atime、mtime、ctime 三时间戳详解与实战避坑

Linux 文件的 atime、mtime、ctime 这三个时间戳,坑人的地方不在于它们有多难懂,而在于你自以为懂了。很多人第一次被它绊倒,都不是在高深场景里,而是在一条看起来人畜无害的清理命令上:写完find /var/log -name "…

📅 2026/9/16 19:09:10
Nginx RTMP流媒体服务器搭建与优化指南

Nginx RTMP流媒体服务器搭建与优化指南

1. 项目概述RTMP(Real-Time Messaging Protocol)作为直播领域沿用至今的经典协议,虽然在Web端逐渐被HLS/DASH等新技术替代,但在专业直播推流、监控系统对接等场景仍是不可替代的基础设施。本文将基于Nginx的RTMP扩展模块&#xff…

📅 2026/9/16 19:09:10
基于MATLAB的惯性/GPS组合导航仿真与卡尔曼滤波实现

基于MATLAB的惯性/GPS组合导航仿真与卡尔曼滤波实现

简介:一套基于Matlab的惯性/GPS组合导航程序集合,面向组合导航、制导与控制方向的科研人员和学生,主要用于轨迹生成、传递对准、惯性/GPS滤波与导航解算等算法验证。包内按功能组织,包含轨迹仿真脚本、滤波解算程序、惯性器件数据…

📅 2026/9/16 19:09:10
MORE NEWS

更多资讯

📰

WPS在Linux下打不开中文文件?KDE桌面启动器修复指南

如果你也是在 Arch Linux 上装 KDE 当主力桌面,又习惯用 WPS 打开同事发来的docx、xlsx、pptx,大概率迟早会撞见这个对话框:WPS 突然弹出来一句“无法找到“”。请检查文件名的拼写,并检查文件位置是否正确。”。我第一次看到的时…

📰

MATLAB实现改进型SEIR3疫情传播模型与参数敏感性分析

简介:本资源是一套面向流行病学建模研究者与公共卫生数据分析学习者的改进型SEIR疫情仿真方案,聚焦COVID-19传播动力学分析,提供可复现、可调参的MATLAB实现框架。压缩包共106个文件,含103份PDF技术文档(含全国每日疫情…

📰

Linux动态库undefined symbol定位与修复实战

上周三晚上十一点,同事在群里甩了一张截图,程序启动直接抛出error while loading shared libraries: libparse.so: undefined symbol: _Z8parse_docPKc,后面跟了一句:本地机器编得好好的,怎么一到部署环境就炸了。这种…

📰

OpenCV轮廓匹配实战:用Hu矩实现5分钟形状识别

开头先聊点实在的。做图像处理这些年,形状识别算是我被问到最多的需求之一:分拣线上的零件方向对不对、PCB板上的元件有没有放反、OCR之前先把目标区域定位出来……这些场景看起来五花八门,但落到OpenCV层面,核心思路高度一致——…

📰

基于ZYNQ的FPGA DDS信号发生器设计与实现

简介:面向FPGA开发者的ZYNQ7100 DDS信号发生器完整工程,主控芯片采用XC7Z100FFG900-2,基于Vivado环境开发实现。工程代码可直接编译运行,并支持向XC7Z100系列其他芯片移植,适合需要快速搭建任意波形发生器或学习ZYNQ平…

📰

内网HTTPS部署:用openssl自签名证书解决Chrome“不安全”提示

内网部署HTTPS:用openssl自签名证书,一次搞定Chrome“不安全”提示先说说我为什么折腾这事。公司内网有套业务系统,一直走HTTP,后来要对接一些对安全性有硬性要求的接口,加上审计也盯得紧,必须上HTTPS。公网…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬