如何检测指定文件夹及扩展名的文件变更并配置Git Hook?
我来帮你一步步搞定这两个实用的开发场景问题:
一、检测选定文件夹中指定扩展名文件的变更
针对这个需求,有几种不同的实现方式,你可以根据场景选择:
1. 命令行快速检测(适合临时手动检查)
如果在Git仓库中:直接用
git status配合过滤就能快速定位变更文件:git status --porcelain | grep "^[AM]" | grep "schemas/.*\.xsd$"解释一下:
--porcelain输出简洁的标准化格式,^[AM]筛选出新增(A)或修改(M)的文件,最后一个grep精准匹配schemas文件夹下所有.xsd后缀的文件。不在Git仓库中:用
find配合哈希校验来对比文件变化:
先生成初始的哈希记录文件:find /path/to/your/schemas -name "*.xsd" -exec md5sum {} \; > xsd_hash_record.txt之后要检测变更时,运行:
find /path/to/your/schemas -name "*.xsd" -exec md5sum {} \; | diff xsd_hash_record.txt -差异部分就是发生变更的文件,包括内容修改、新增或删除的文件都会被检测到。
2. 脚本自动化检测(适合定期或集成到工作流)
写个简单的Python脚本,能自动记录文件状态并对比变更,比命令行更灵活:
import os import hashlib from pathlib import Path def get_file_md5(file_path): """计算文件的MD5哈希值""" with open(file_path, 'rb') as f: return hashlib.md5(f.read()).hexdigest() def check_xsd_changes(target_folder): # 用来存储哈希记录的文件,可自定义路径 record_file = Path("xsd_change_tracker.txt") current_file_hashes = {} # 遍历目标文件夹下所有.xsd文件 for xsd_file in Path(target_folder).rglob("*.xsd"): current_file_hashes[str(xsd_file)] = get_file_md5(xsd_file) if record_file.exists(): # 读取之前的哈希记录 old_file_hashes = {} with open(record_file, 'r') as f: for line in f: file_path, hash_val = line.strip().split(' ', 1) old_file_hashes[file_path] = hash_val # 对比找出变更的文件 changed_files = [] deleted_files = [] for path, new_hash in current_file_hashes.items(): if path not in old_file_hashes or old_file_hashes[path] != new_hash: changed_files.append(path) for path in old_file_hashes: if path not in current_file_hashes: deleted_files.append(path) # 输出结果 if changed_files: print("✅ 检测到修改/新增的XSD文件:") for f in changed_files: print(f"- {f}") if deleted_files: print("❌ 检测到删除的XSD文件:") for f in deleted_files: print(f"- {f}") if not changed_files and not deleted_files: print("ℹ️ 没有XSD文件发生变更") else: # 第一次运行,初始化哈希记录 with open(record_file, 'w') as f: for path, hash_val in current_file_hashes.items(): f.write(f"{path} {hash_val}\n") print("🔧 已初始化XSD文件哈希记录,下次运行即可检测变更") if __name__ == "__main__": # 替换成你的目标文件夹路径 check_xsd_changes("/path/to/your/schemas")
你可以根据需要调整脚本逻辑,比如换成SHA-256哈希,或者把记录文件放到特定目录。
二、配置Git Hook检测特定文件夹和扩展名的文件
Git Hooks是仓库本地的脚本,能在提交、推送等操作前自动触发。这里我们用pre-commit钩子(提交前检测)来实现需求:
1. 创建并激活钩子脚本
进入你的Git仓库,找到.git/hooks目录,创建pre-commit文件(注意没有后缀):
cd .git/hooks touch pre-commit chmod +x pre-commit # 必须赋予执行权限,否则钩子不会运行
2. 编写钩子检测逻辑
打开pre-commit文件,写入以下shell脚本:
#!/bin/bash # 配置要检测的目标文件夹和扩展名(根据你的实际情况修改) TARGET_DIR="schemas" TARGET_EXT=".xsd" # 获取本次提交中所有新增/修改/复制的文件 CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACM) # 过滤出目标文件夹下的目标扩展名文件 TARGET_CHANGES=$(echo "$CHANGED_FILES" | grep "^${TARGET_DIR}/.*${TARGET_EXT}$") if [ -n "$TARGET_CHANGES" ]; then echo "⚠️ 检测到${TARGET_DIR}文件夹下的${TARGET_EXT}文件发生变更:" echo "$TARGET_CHANGES" # 这里可以添加自定义逻辑,比如: # 1. 强制运行XSD校验脚本 # ./scripts/validate_xsd.sh "$TARGET_CHANGES" # 2. 阻止不符合要求的提交(取消下面两行注释即可) # echo "❌ 错误:不允许直接修改XSD文件,请遵循指定流程!" # exit 1 else echo "ℹ️ 未检测到${TARGET_DIR}文件夹下的${TARGET_EXT}文件变更" fi # 没有问题就允许提交 exit 0
3. 测试钩子功能
修改schemas目录下的某个.xsd文件,执行git add和git commit,钩子会自动运行并输出检测结果。如果需要阻止违规提交,把脚本里的exit 1注释去掉即可。
小提示
- Git钩子是仓库本地的,如果你想团队共享这个钩子,可以把脚本放到项目根目录(比如
scripts/git-hooks/pre-commit),然后让团队成员手动复制到.git/hooks,或者写个简单的安装脚本自动复制。 - 脚本中的
TARGET_DIR要使用相对于仓库根目录的路径,比如如果schemas在项目根目录下,就写"schemas";如果是src/schemas,就写"src/schemas"。
内容的提问来源于stack exchange,提问作者Slava Podolskiy
相关产品推荐
相关产品推荐

