You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测指定文件夹及扩展名的文件变更并配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:20:01