如何在pre-commit钩子中处理git diff返回的非ASCII文件名?
解决pre-commit钩子中含非ASCII字符文件名的处理问题
问题本质是Git默认开启了core.quotepath配置,会将非ASCII文件名转义为带双引号的八进制格式(比如"\341\203\236..."),直接处理这种字符串会因为系统真实文件名是Unicode字符而无法匹配,导致找不到文件。以下是两种实用解决方法:
方法一:临时关闭Git的quotepath配置(推荐)
直接修改git diff命令,临时关闭转义输出,获取原始Unicode文件名:
files=$(git -c core.quotepath=false diff --cached --name-only --diff-filter=ACMR | grep -E "$extension_regex")
之后直接遍历$files执行格式化操作即可,无需额外处理转义或引号。
方法二:解码八进制转义字符串
如果无法修改Git配置,可对每个转义后的文件名进行解码:
# 逐行处理输出的文件名,避免空格/特殊字符拆分问题 while IFS= read -r quoted_file; do # 移除前后的双引号 escaped_file="${quoted_file:1:-1}" # 用printf解码八进制转义序列,还原真实文件名 real_file=$(printf "%b" "$escaped_file") # 执行你的格式化操作,比如: # your_format_command "$real_file" done < <(git diff --cached --name-only --diff-filter=ACMR | grep -E "$extension_regex")
注意事项
- 始终用双引号包裹文件名变量(如
"$real_file"),防止文件名含空格或特殊字符时被错误拆分 - 优先使用
$()替代反引号`,避免嵌套命令时的转义冲突
内容的提问来源于stack exchange,提问作者Guiorgy
相关产品推荐
相关产品推荐

