Python实现一个Git日志统计分析的小工具


Posted in Python onDecember 14, 2017

前言

本文介绍的是利用Python实现的一个小工具,用于分析Git commit log,获得Git Project每个成员的简单行为数据。

Warning:代码量不能代表程序员能力水平!

启动参数

共5个。

  • Repo地址
  • Commit 起始日期
  • Commit 结束日期
  • Git仓库子目录
  • 统计分析结果CSV文件目标路径

exec_git

Git Log命令:

git -C {} log --since={} --until={} --pretty=tformat:%ae --shortstat --no-merges -- {} > {}

填入参数,调用系统命令'os.system()',输出结果至本地临时文件。读取至内存,简单的String Array。

parse

Git Log输出有3种格式,对应3种正则表达式。

REPATTERN_FULL = r"\s(\d+)\D+(\d+)\D+(\d+)\D+\n"
REPATTERN_INSERT_ONLY = r"\s(\d+)\D+(\d+)\sinsertion\D+\n"
REPATTERN_DELETE_ONLY = r"\s(\d+)\D+(\d+)\sdeletion\D+\n"

遍历得到的数据,首先构造一个以Author为Key,分析结果为Value的字典。

分析结果构造一个元祖,包括:

  • Commit 次数
  • 增加代码行数
  • 删除代码行数
  • 变更代码行数

save_csv

简单省略。

示例代码:

#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
'''Analyse git branch commit log, for every version, every person.'''
import os
import sys
import re
import csv
GIT_LOG = r'git -C {} log --since={} --until={} --pretty=tformat:%ae --shortstat --no-merges -- {} > {}'
REPATTERN_FULL = r"\s(\d+)\D+(\d+)\D+(\d+)\D+\n"
REPATTERN_INSERT_ONLY = r"\s(\d+)\D+(\d+)\sinsertion\D+\n"
REPATTERN_DELETE_ONLY = r"\s(\d+)\D+(\d+)\sdeletion\D+\n"
CSV_FILE_HEADER = ["Author", "Commit", "Insert", "Delete", "Loc"]
def exec_git(repo, since, until, subdir):
 '''Execute git log commant, return string array.'''
 logfile = os.path.join(os.getcwd(), 'gitstats.txt')
 git_log_command = GIT_LOG.format(repo, since, until, subdir, logfile)
 os.system(git_log_command)
 lines = None
 with open(logfile, 'r', encoding='utf-8') as logfilehandler:
 lines = logfilehandler.readlines()
 return lines
def save_csv(stats, csvfile):
 '''save stats data to csv file.'''
 with open(csvfile, 'w', encoding='utf-8') as csvfilehandler:
 writer = csv.writer(csvfilehandler)
 writer.writerow(CSV_FILE_HEADER)
 for author, stat in stats.items():
  writer.writerow([author, stat[0], stat[1], stat[2], stat[3]])
def parse(lines):
 '''Analyse git log and sort to csv file.'''
 prog_full = re.compile(REPATTERN_FULL)
 prog_insert_only = re.compile(REPATTERN_INSERT_ONLY)
 prog_delete_only = re.compile(REPATTERN_DELETE_ONLY)
 stats = {}
 for i in range(0, len(lines), 3):
 author = lines[i]
 #empty = lines[i+1]
 info = lines[i+2]
 #change = 0
 insert, delete = int(0), int(0)
 result = prog_full.search(info)
 if result:
  #change = result[0]
  insert = int(result.group(2))
  delete = int(result.group(3))
 else:
  result = prog_insert_only.search(info)
  if result:
  #change = result[0]
  insert = int(result.group(2))
  delete = int(0)
  else:
  result = prog_delete_only.search(info)
  if result:
   #change = result[0]
   insert = int(0)
   delete = int(result.group(2))
  else:
   print('Regular expression fail!')
   return
 loc = insert - delete
 stat = stats.get(author)
 if stat is None:
  stats[author] = [1, insert, delete, loc]
 else:
  stat[0] += 1
  stat[1] += insert
  stat[2] += delete
  stat[3] += loc
 return stats
if __name__ == "__main__":
 print('gitstats begin')
 if len(sys.argv) != 6:
 print('Invalid argv parameters.')
 exit(0)
 REPO = os.path.join(os.getcwd(), sys.argv[1])
 SINCE = sys.argv[2]
 UNTIL = sys.argv[3]
 SUB_DIR = sys.argv[4]
 CSV_FILE = os.path.join(os.getcwd(), sys.argv[5])
 LINES = exec_git(REPO, SINCE, UNTIL, SUB_DIR)
 assert LINES is not None
 STATS = parse(LINES)
 save_csv(STATS, CSV_FILE)
 print('gitstats done')

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python文件操作之目录遍历实例分析
May 20 Python
在Linux命令行终端中使用python的简单方法(推荐)
Jan 23 Python
Python输出带颜色的字符串实例
Oct 10 Python
tf.truncated_normal与tf.random_normal的详细用法
Mar 05 Python
pandas 小数位数 精度的处理方法
Jun 09 Python
python3.6.3转化为win-exe文件发布的方法
Oct 31 Python
python通过tcp发送xml报文的方法
Dec 28 Python
python代码实现逻辑回归logistic原理
Aug 07 Python
django框架cookie和session用法实例详解
Dec 10 Python
python实现从尾到头打印单链表操作示例
Feb 22 Python
简单了解Python字典copy与赋值的区别
Sep 16 Python
python实现三种随机请求头方式
Jan 05 Python
用matplotlib画等高线图详解
Dec 14 #Python
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
Dec 14 #Python
python实现发送邮件功能代码
Dec 14 #Python
python正则实现计算器功能
Dec 14 #Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
Dec 14 #Python
python实现BackPropagation算法
Dec 14 #Python
python实现随机梯度下降(SGD)
Mar 24 #Python
You might like
is_uploaded_file函数引发的不能上传文件问题
2013/10/29 PHP
PHP实现的英文名字全拼随机排号脚本
2014/07/04 PHP
Laravel中基于Artisan View扩展包创建及删除应用视图文件的方法
2016/10/08 PHP
Yii2配置Nginx伪静态的方法
2017/05/05 PHP
PHP使用正则表达式实现过滤非法字符串功能示例
2018/06/04 PHP
PHP fprintf()函数用法讲解
2019/02/16 PHP
基于jquery的tab切换 js原理
2010/04/01 Javascript
JS的反射问题
2010/04/07 Javascript
浅谈javascript中call()、apply()、bind()的用法
2015/04/20 Javascript
jquery实现鼠标滑过后动态图片提示效果实例
2015/08/10 Javascript
浅谈javascript 函数表达式和函数声明的区别
2016/01/05 Javascript
jquery对所有input type=text的控件赋值实现方法
2016/12/02 Javascript
jQuery实现别踩白块儿网页版小游戏
2017/01/18 Javascript
nodejs个人博客开发第五步 分配数据
2017/04/12 NodeJs
详解vuejs之v-for列表渲染
2017/06/22 Javascript
解决vue-router进行build无法正常显示路由页面的问题
2018/03/06 Javascript
Vue与Node.js通过socket.io通信的示例代码
2018/07/25 Javascript
Vue 中对图片地址进行拼接的方法
2018/09/03 Javascript
js实现每日签到功能
2018/11/29 Javascript
jQuery+vue.js实现的多选下拉列表功能示例
2019/01/15 jQuery
详解为element-ui的Select和Cascader添加弹层底部操作按钮
2020/02/07 Javascript
JavaScript类的继承多种实现方法
2020/05/30 Javascript
重命名批处理python脚本
2013/04/05 Python
用Python编写web API的教程
2015/04/30 Python
python获取指定路径下所有指定后缀文件的方法
2015/05/26 Python
python中reduce()函数的使用方法示例
2017/09/29 Python
Python:Scrapy框架中Item Pipeline组件使用详解
2017/12/27 Python
解决Python列表字符不区分大小写的问题
2019/12/19 Python
python 递归相关知识总结
2021/03/03 Python
HTML5实现锚点时请使用id取代name
2013/09/06 HTML / CSS
上课迟到检讨书100字
2014/01/11 职场文书
创建无烟单位实施方案
2014/03/29 职场文书
体育课外活动总结
2014/07/08 职场文书
小学教师暑期培训方案
2014/08/28 职场文书
党课培训心得体会
2014/09/02 职场文书
一个独生女的故事观后感
2015/06/04 职场文书