Git预提交钩子优化:合并提交时仅检查冲突解决的PHP文件
解决Git合并提交时预提交钩子仅检查用户修改文件的问题
核心思路
要实现合并提交时仅检查用户手动编辑(解决冲突或主动修改)的PHP文件,关键是区分Git自动合并的文件和用户手动修改的文件:
- 普通提交场景:保留原有的lint检查逻辑
- 合并提交场景:对比每个变更文件的Git自动合并结果与暂存区内容,仅检查内容不一致的文件(即用户修改过的)
修改后的预提交钩子脚本
替换原有的钩子逻辑,使用以下脚本:
#!/bin/bash # 初始化待检查文件列表 target_files="" # 判断当前是否处于合并提交状态 if git rev-parse --verify -q MERGE_HEAD > /dev/null; then # 获取合并的基础版本哈希 merge_base=$(git merge-base HEAD MERGE_HEAD) # 获取两个分支间所有变更的PHP文件 merge_changed_files=$(git diff --name-only --diff-filter=ACM "$merge_base" MERGE_HEAD -- '*.php') for file in $merge_changed_files; do # 提取Git自动合并后的文件内容(过滤掉merge-tree的元信息) auto_merged_content=$(git merge-tree "$merge_base" HEAD MERGE_HEAD -- "$file" | sed -n '/^@@/,$p' | sed '1d') # 提取暂存区的文件内容 staged_content=$(git show :"$file") # 对比内容:不一致说明用户手动修改过该文件 if [ "$auto_merged_content" != "$staged_content" ]; then target_files="$target_files $file" fi done else # 普通提交场景:沿用原逻辑获取待检查文件 target_files=$(git diff --cached --name-only --diff-filter=ACM -- '*.php') fi # 运行PHP lint检查 if [ -n "$target_files" ]; then echo "执行PHP lint检查:$target_files" php -l $target_files if [ $? -ne 0 ]; then echo "PHP lint检查失败,请修复错误后再提交。" exit 1 fi fi exit 0
脚本说明
- 合并状态判断:通过
git rev-parse --verify -q MERGE_HEAD检测是否处于合并流程中 - 自动合并内容对比:
- 用
git merge-tree获取Git自动合并后的文件内容 - 用
git show :"$file"获取暂存区中用户实际提交的内容 - 两者内容不一致,说明用户手动修改过该文件(解决冲突或主动编辑)
- 用
- 普通提交兼容:非合并场景下保留原有的文件筛选逻辑,不影响日常提交
注意事项
- 确保Git版本兼容:
git merge-tree的输出格式在Git 2.30+版本中稳定,若使用旧版本可能需要调整sed过滤规则 - 性能优化:脚本仅对用户修改过的文件执行lint,相比原逻辑大幅减少合并时的检查量,同时保障代码质量
内容的提问来源于stack exchange,提问作者André Walker
相关产品推荐
相关产品推荐

