如何在git log中结合--pretty=format输出numstat/stat的JSON格式结果?
获取git log中stat和numstat的JSON格式输出
你说得对,git log的--pretty=format确实不支持直接用%stat或%numstat作为占位符——这两个参数是独立的输出选项,会在每个提交的格式化内容后追加对应的统计信息,没法直接嵌入到自定义格式里。不过有几种原生工具结合的方法能实现你想要的JSON输出:
方法1:用awk/sed手动拼接JSON(无需额外工具)
这个方法通过标记每个提交的起始,然后用awk捕获stat和numstat的内容,最后拼接成合法的JSON数组:
git log --author="<author-name>" --pretty=format:'START_COMMIT {"commit": "%H", "author": "%an", "date": "%ad"}' --numstat --stat=short | awk ' # 处理提交起始标记,初始化当前提交的JSON /^START_COMMIT/ { if (current_commit != "") print current_commit "," current_commit = substr($0, 14) numstat_list = "" next } # 处理numstat行(格式:添加行数 删除行数 文件名) /^[0-9]/ { numstat_list = numstat_list "{\"added\": "$1", \"deleted\": "$2", \"file\": \""$3"\"}," next } # 处理stat的汇总行(比如 "3 files changed, 10 insertions(+), 2 deletions(-)") /^ [0-9]+ files? changed/ { # 转义字符串里的双引号(如果有的话) gsub(/"/, "\\\"", $0) # 把stat和numstat追加到当前提交的JSON中 current_commit = current_commit ", \"stat\": \""$0"\", \"numstat\": [" substr(numstat_list, 1, length(numstat_list)-1) "]" } # 最后输出所有提交,包裹成JSON数组 END { print "[" current_commit "]" } '
方法2:用jq简化JSON处理(推荐,需安装jq)
如果你系统里有jq(一款轻量的JSON处理工具,大部分Linux/macOS包管理器都能安装),这个方法更简洁可靠:
git log --author="<author-name>" --pretty=format:'{"commit":"%H","author":"%an","date":"%ad"}' | jq -c ' . + { # 获取当前提交的stat汇总,去掉前两行的提交信息 stat: (git show --stat=short \(.commit) | tail -n +2 | paste -s -d " "), # 获取numstat并转成结构化的JSON数组 numstat: (git show --numstat \(.commit) | jq -R . | jq -sr " map( split(\"\\t\") | {added: .[0] | tonumber?, deleted: .[1] | tonumber?, file: .[2]} ) ") } ' | jq -s '.'
这个方法的思路是:先输出每个提交的基础信息,再用jq调用git show单独获取每个提交的stat和numstat,最后把这些内容合并成完整的JSON对象,再用jq -s把所有对象包裹成数组。
补充说明
为什么直接用--pretty=format不行?因为--stat和--numstat属于git log的"输出辅助选项",它们的输出逻辑是在格式化内容之后追加,而不是作为可嵌入的变量。所以必须通过后续的文本处理工具,把这些追加的内容整合到JSON结构里。
内容的提问来源于stack exchange,提问作者Alexander Mills
相关产品推荐
相关产品推荐

