git show --name-only 可列出某次提交修改的文件路径,不显示代码差异;加 -p 显示具体增删内容,--stat 显示行数统计,-m 用于合并提交的父提交对比。

怎么用 Git 命令提取某个分支所有修改的文件后缀
直接靠 git log 或 git diff 本身不输出文件类型,得组合命令筛出后缀。关键不是“看有哪些文件”,而是“哪些文件被改过”——要区分是新增、修改还是删除,但统计类型时通常只关心路径存在且有变更的文件。
实操建议:
- 用
git log --name-only --pretty=format: HEAD --no-merges获取当前分支所有提交中涉及的文件路径(不含重复) - 过滤空行和目录:加
| grep -v '^$' | grep -v '/$' - 提取后缀:用
awk -F. '{print $NF}'不够健壮(比如.tar.gz会被切错),更可靠的是sed 's/.*\.//' | grep -v '^$' - 注意:二进制文件(如图片、PDF)也会出现在结果里,但
git diff默认不显示其内容变更,统计时是否纳入取决于需求
统计多个分支时如何避免重复计算同一文件
不同分支可能都改过 package.json,但你通常想看“每个分支各自改了哪些类型”,而不是“全量去重后统计”。所以不能先合并所有路径再分类,必须按分支隔离处理。
实操建议:
- 对每个目标分支,先
git checkout -q <branch></branch>(-q避免输出干扰),再执行日志提取,最后git checkout -q -回退 - 不要用
git log <branch1>..<branch2></branch2></branch1>算差异——它只反映“从 branch1 到 branch2 新增的提交”,漏掉 branch1 自身独有的修改 - 若分支已合并进 main,又想排除共用部分,可用
git log <branch> ^main --name-only --pretty=format:</branch>(注意^表示排除) - 临时工作区污染风险高,建议在克隆副本或用
git worktree隔离分支环境
Shell 脚本里怎么汇总并排序显示类型频次
单纯 sort | uniq -c | sort -nr 能排序,但容易把大小写不同的后缀(如 JS 和 js)当不同项;另外像 .jsx 和 .js 是否合并,得按项目规范定。
实操建议:
- 统一转小写:
tr '[:upper:]' '[:lower:]'放在sed提取后缀之后 - 过滤无效后缀(如空字符串、纯数字、单字母):
grep -E '^[a-z0-9]{2,}$' - 用
awk '{count[$0]++} END {for (i in count) print count[i], i}' | sort -k1,1nr -k2,2替代管道链,更可控 - 如果要导出 CSV,别用
echo拼接,用printf "%s,%s\n" "$count" "$ext"防止逗号在后缀里(如.csv)引发解析错误
Python 版本脚本比 Shell 更稳吗
纯 Shell 在处理含空格、换行符的文件名时容易崩(虽然 Git 日志一般不带换行,但不能假设)。Python 的 subprocess + pathlib 更安全,且方便后续扩展(比如按类型分组查行数、跳过 node_modules)。
实操建议:
- 用
git log --name-only --pretty=format: --no-merges --all获取原始输出,然后splitlines()处理,比 shell 的while read可靠 - 提取后缀用
Path(filename).suffix.lstrip('.').lower(),自动处理.tar.gz→tar.gz(suffix返回完整后缀) - 避免硬编码分支列表:用
git branch --format='%(refname:short)'动态获取本地分支 - 性能上,1000+ 提交时 Python 启动开销略高,但逻辑清晰度和容错性明显胜出
真正麻烦的不是写统计逻辑,而是定义“什么是修改”——merge commit 里的文件要不要算、rebase 后的提交哈希变了怎么对齐、 submodule 里的变更是否计入。这些没标准答案,得看团队怎么约定 baseline。











