在网上很容易就可以搜到相关的代码,现在予以分析

首先先拿一个可以运行的代码出来:

git log --pretty=tformat: --numstat | awk '{add+=$1;subs+=$2;}END{printf "+%s -%s %s",add,subs,add-subs}'

语句共分为两部分:

  1. git log 按格式输出行数统计
  2. awk 按照管道输出逐行统计

首先,--pretty是按照要求输出log内容。
常用的是--pretty:oneline,这样只输出哈希值和commit信息
--pretty:format--pretty:tformat则是按照自定义格式输出内容的命令
常用的转义字符有

转义字符 含义
%s commit信息
%h 简短hash值
%H 完整hash值
%an 作者名字
%ae 作者邮箱
%ad 作者修订日期
%cn 提交者名字
%ce 提交者邮箱
%cd 提交日期

当然,这些内容属于标题,也即第一行的内容。具体的文件变动不会显示。
因此,需要配合别的指令显示具体的操作

转义字符 含义
--graph 图形方式的log
--stat 所有文件的增减行数统计信息
--shortstat 简短的文件行数信息
--name-only 只显示涉及的文件名
--name-status 增删改分类的文件名
--numstat 增删行数与文件名

结合上面两者,就可以完美显示出每次commit的信息以及变动内容。
当format后的自定义信息为空时,相当于不存在标题行,这时,如果是--pretty:format:则会输出一个空行,--pretty:tformat:则不会有空行。

那么要输出行数信息,就很明显,应该使用--pretty:tformat: --numstat或者--pretty:tformat: --shortstat
前者行数多,但处理方便;后者行数少,但不宜处理

前者的输出内容大致是

git log --pretty=tformat: --numstat
1       0       .gitignore
3       1       config.py
1       1       stop.sh
0       0       OBlog/templates/layout/{robot.txt => robots.txt}
2       2       OBlog/views.py
30      28      OBlog/static/js/local.js
1       4       OBlog/templates/layout/comments.js
1       2       OBlog/templates/pages/index.html
26      25      OBlog/templates/pages/404.html
2       2       OBlog/templates/layout/jscss.html
……

后者则是

git log --pretty=tformat: --shortstat
 3 files changed, 5 insertions(+), 2 deletions(-)
 2 files changed, 2 insertions(+), 2 deletions(-)
 3 files changed, 32 insertions(+), 34 deletions(-)
 1 file changed, 26 insertions(+), 25 deletions(-)
 1 file changed, 2 insertions(+), 2 deletions(-)
……

这样,我们就获得了每次提交的变更的代码行数。
剩下的只需要统计每行的信息即可。

要按行执行指令,则要用到awk
通过|将指令连接,awk可以逐行执行指定命令。
逐行输出:awk '{print $0}
逐行输出空格分隔后的第一个参数:awk '{print $1}

同理,要求和第一个参数就是 awk '{add+=$1}'
然后我们则需要在最后输出值,要用到END{},这表示只在运行结束时执行。
awk '{add+=$1;subs+=$2}END{printf "+%s -%s",add,subs}'
这样就实现了增删行数的统计。