阿捷外传之Git代码统计:DotNetCore + PowerBI 实现Git仓库日志分析

前言

2020年3月初春,虽然春节已经过去一个多月,大街上还未恢复往年的热闹。由于春节前夕突然降临的冠状病毒,导致很多员工无法回到城市复工。春节之后,阿捷所在的公司考虑到复工带来的风险,通知所有员工以远程的方式在家办公。

某一天,PM联系到阿捷,说目前有一个需求,想要对各个项目组的Git仓库提交信息进行相关统计,让阿捷调研一下。于是阿捷查了一番资料,了解到可以直接用原生 Git 命令行的方式来实现。

即使用内置的 git log 命令,提取仓库下的提交日志。

实践经过

git log 默认的输出格式是下面这个样子:

其中,上面的输出内容里主要包含了以下4种信息:

  • Commit 信息,每次提交的一个hash值;

  • Author 相关信息,提交的作者和及邮箱信息;

  • Commit Message, 提交时填写的信息,可能会包含多行文字。

Date 信息,这个信息中除了有日期时间,还包含时区信息。例如,从上图中可以看到有一条记录的日期为 Mon Mar 2 22:06:13 2020 -0800,其中最后的 -0800 就是所在的时区,即西八区,根据时区地图,可以看到 -0800是在美国西部湾区。中国处于东八区,所以如果是在中国提交的话,时区部分将会是 +0800 。

除了以上的4个基础信息,PM还想要拿到每次提交时变动的代码行数,阿捷通过查询Git Log 的命令行文档,了解到可以通过追加配置项 git log --shortstat 来输出变更的行数,如下图所示。

另外,git log 也考虑到输出格式化的问题,可以使用特殊的占位符指定输出格式。经过反复实验,优化后的命令如下:

git log --all --pretty="%x40%h%x2C%an%x2C%ad%x2C%x22%s%x22%x2C" --shortstat | tr "\n" " " | tr "@" "\n"

通过上面的魔幻配置,基本上能从每条提交记录中提取出需要的列,然后用逗号方式进行拼接,最终可以生成出CSV格式的文件。

然而这种方式始终不够优雅,命令中额外使用了 tr 对字符串进行处理,这意味着在目标机器上也要有这个工具,否则无法运行,而 windows 上只能通过安装第三方工具实现。

另外一点是扩展性问题,命令行对于csv这种简单的格式处理还好说,如果要输出JSON格式的话,就不好办了,而且命令行的配置项几乎没人能看懂,以后维护起来免不了要996。

基于上述痛点,阿捷又在网上搜寻了一番,最终在MVP大佬的一篇博客(https://edi.wang/post/2019/3/26/operate-git-with-net-core)中找到了蛛丝马迹。根据博客中的内容来看,可以通过一款名为libgit2sharp(https://github.com/libgit2/libgit2sharp)的类库,实现我们的需求。

libgit2sharp内部嵌套了一个基于C语言实现的Git内核,它自身对外提供一系列和Git操作相关的接口,并且它的上游核心仓库libgit2(https://github.com/libgit2/),提供了对包括Python,PHP,C#在内的多种语言的支持。而且项目是开源的,由社区进行维护。

阿捷经过简单上手,觉得提供的API可以满足需要,然后快速制作出了一个简易的命令行程序。核心代码如下:

using (var repo = new Repository(workdir))
{Console.WriteLine("all commit count:" + repo.Commits.Count());foreach (Commit commit in repo.Commits){var commitDto = new GitCommitLogDto{CommitHash = commit.Sha,AuthorName = commit.Author.Name,AuthorEmail = commit.Author.Email,MessageShort = commit.MessageShort,AuthorDate = commit.Author.When.DateTime,};var patch = GetPatchInfo(repo, commit);if (patch != null){commitDto.LinesAdded = patch.LinesAdded;commitDto.LinesDeleted = patch.LinesDeleted;};Console.WriteLine(commitDto.ToString());list.Add(commitDto);}
}

由于有了良好封装和结构化数据的支持,理论上可以将结果转化成任何格式,包括CSV,JSON,XML等,并且可以很方便地对数据格式进行任意加工。

考虑到工具在实际使用时,面临着跨平台和环境依赖的问题,于是阿捷使用了DoNetCore3.0提供的新特性,将程序打包成了不依赖安装环境的可执行文件,不需要安装外部依赖,开箱即用,最终打包的命令如下:

# publish win-x64
dotnet publish -c Release -o publish/win-x64 -r win-x64 /p:PublishSingleFile=true /p:IncludeSymbolsInSingleFile=true /p:PublishTrimmed=true#publish linux-x64
dotnet publish -c Release -o publish/linux-x64 -r linux-x64 /p:PublishSingleFile=true /p:IncludeSymbolsInSingleFile=true /p:PublishTrimmed=true

然后因为是开源项目,可以用GitHub的高性能构建机器,阿捷使用了yml文件为项目制作了自动构建的流水线,每次提交代码后自动触发编译生成出新的二进制文件。

除了CSV文件的部分,PM那还需要制作出相关报表,对CSV中的数据进行统计。阿捷考察了目前市面上流行的BI工具,最终选择了免费的PowerBI桌面版(https://powerbi.microsoft.com/zh-cn/)。

PowerBI是由微软出品的一款专业的用于商业智能方向的报表工具,桌面版内嵌了一套高性能的计算引擎,不需要安装任何依赖,开箱即用。而且支持的数据源种类非常多,CSV文件完全不在话下。

阿捷首先用吃狗粮的态度,用自己制作的命令行工具,从AspNetCore(https://github.com/dotnet/aspnetcore)的官方Github仓库中提取出了共计4万多提交信息,数据如下:

然后,阿捷经过对PowerBI简单的上手,制作出了下面几张报表。

上图中可以看到AspNetCore中仓库提交记录是最早从2013年开始的。

上图中,可以看到2017和2018年是提交次数和增加行数最多的一年,参考aspnetcore的发布时间,可以知道这期间经历了从1.1到2.0和2.2之间的迭代。

上面两张图展示了根据提交者的邮箱后缀,对提交次数和增加行数的统计。可以看出,来自微软员工的提交占了相当的分量,并且来自外部的贡献者也很广泛,说明AspNetCore有着广泛的社区贡献者。

上述两种图展示 的提交的日期主要分布在周一到周五之间的工作日,在提交的时间分布上,主要集中在上午10点到下午5点之间。

后记

有了DotNetCore和PowerBI的助力,阿捷很轻松地搞定了PM的需求,为了发扬回馈社区的精神,阿捷将项目托管在了GitHub上,仓库链接:https://github.com/leansoftX/dotnet-gitstats。有需要的小伙伴可以直接拿来食用。目前项目还在早期阶段,欢迎动手能力强的小伙伴增加新功能,提交ISSUE或PR。

参考资源

  • Git Log 命令行文档(https://git-scm.com/docs/git-log)

  • libgit2sharp上手博客(https://edi.wang/post/2019/3/26/operate-git-with-net-core)

  • libgit2sharp 上手wiki(https://github.com/libgit2/libgit2sharp/wiki/git-log)

  • PowerBI下载地址(https://www.microsoft.com/en-us/download/details.aspx?id=58494)

本周二(今天)晚8点,Boat House共创迭代会议直播????

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311277.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

递归算法(三)- 回溯法Backtracking

回溯法 回溯法Backtracking(找所有的可能)递归: 类似枚举,一层一层向下递归,尝试搜索答案。找到答案: > 返回答案,并尝试别的可能未找到答案: > 返回上一层递归,…

一个全栈式的应用集成平台,打破“信息孤岛”

源宝导读:随着企业数字化进程的逐渐深入,企业存在大量的异构系统,各个系统之间信息传输、资源利用困难。本文将介绍明源云ERP为了打破这种“信息孤岛”,而进行的思考与实践。一、前言随着企业信息化进程的逐步深入,互联…

【朝夕技术专刊】Core3.1WebApi_Filter多种注册方式支持依赖注入

欢迎大家阅读《朝夕Net社区技术专刊》第5期我们致力于.NetCore的推广和落地,为更好的帮助大家学习,方便分享干货,特创此刊!很高兴你能成为忠实读者,文末福利不要错过哦!01PARTCoreFilter多种注册方式在上一…

SQL(一)- 数据库介绍与基础操作

数据库介绍 一、常用的数据库分为两大类: 关系型数据库非关系型数据库(NoSql) 关系型数据库 概念:是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。 关系型数据库的优势&am…

opencv +数字识别

现在很多场景需要使用的数字识别,比如银行卡识别,以及车牌识别等,在AI领域有很多图像识别算法,大多是居于opencv 或者谷歌开源的tesseract 识别.由于公司业务需要,需要开发一个客户端程序,同时需要在xp这种…

SQL(二)- 基础查询语句

简单的查询语句(DQL) 下面我们正式来学习查询语句,下面所有查询用到的表均为前面提到的三张表: 员工表中的数据: 部门表中的数据: 薪资表中的数据: 基本查询语句的语法: sele…

SQL(三)- 连接查询

连接查询概念 一、什么是连接查询? 在实际开发中,大部分的情况下都不是从单张表中查询数据,一般都是多张表联合查询最终取出最终结果。在实际再发中,一般一个业务都会对应多张表,比如学生和班级,最起码两…

远程办公也可以很高效

题图:我的站立办公环境因为疫情,全中国人民都过了一个难忘的春节,而身在武汉的我,更是没有出家门半步,坚决做到不过国家添乱。从开始的2月14到后来的2月20日,再到现在的3月10日,官方发布的复工日…

SQL(四) - 子查询和union以及limit分页

子查询概念 什么是子查询?子查询都可以出现在哪里? select语句当中嵌套select语句,被嵌套的select语句是子查询。 子查询可以出现在哪里? select..(select). from..(select). where..(select).1.where子句中使用子查询 案例&a…

ASP.NET Core中的Http缓存

ASP.NET Core中的Http缓存Http响应缓存可减少客户端或代理对 web服务器发出的请求数。响应缓存还减少了 web服务器生成响应所需的工作量。响应缓存由 Http请求中的 header控制。而 ASP.NETCore对其都有相应的实现,并不需要了解里面的工作细节,即可对其进…

SQL(五) - 表的创建以及操作

创建表 建表语句的语法格式: create table 表名(字段名1 数据类型,字段名2 数据类型,字段名3 数据类型,....);MySql常用数据类型 BLOB 二进制大对象(存储图片、视频等流媒体信息) Binary Large OBject (对应java中的Object&…

Istio 2020 年 Roadmap——一切为了商用

原文地址:https://preliminary.istio.io/zh/blog/2020/tradewinds-2020/,由 ServiceMesher 社区翻译。Istio 解决了人们在运行微服务时遇到的实际问题。甚至早期的预发行版本就已经可以帮助用户诊断其体系架构中的延迟,提高服务的可靠性以及透…

SQL(七) - 事务、索引、视图

事务(Transaction) 3.1、什么是事务? 一个事务是一个完整的业务逻辑单元,不可再分。 比如:银行账户转账,从A账户向B账户转账10000.需要执行两条update语句: update t_act set balance balan…

如何编写高性能的C#代码(二)

使用Benchmark.NET对C# 代码进行基准测试的简介在我以前的文章中[10],我介绍了该系列文章[11],在其中我将分享我的经验,同时了解C#和.NET Core(corefx)框架的新性能。在本文中,我想着重于对现有…

如何编写高性能的C#代码(一)

原文来自互联网,由长沙DotNET技术社区编译。如译文侵犯您的署名权或版权,请联系小编,小编将在24小时内删除。作者介绍:史蒂夫戈登(Steve Gordon)是Microsoft MVP,Pluralsight的作者,…

从Java转向.NET/C#,Are You OK?

最近由于项目变动,需要用.NET/C#做开发,经过一段时间的学习和培训,对这个技术栈有了一定的理解。大家可能都知道Java和.NET/C#很像,这里粗略的把两者做一个对比,希望对感兴趣的童鞋有所帮助。如果现在有人问我&#xf…

树的节点值之和

题目背景 墨家家主有棵树。 题目描述 给定一个保存树节点信息的数据结构,它包含了树节点唯一的 id ,树节点值 和 直系子节点的 id 。 比如,树节点1是树节点2的父节点,树节点2是树节点3的父节点。他们相应的树节点值为 9 , 4 , …

.NET Core开发实战(第21课:中间件:掌控请求处理过程的关键)--学习笔记(上)...

21 | 中间件:掌控请求处理过程的关键这一节讲解一下如何通过中间件来管理请求处理过程中间件工作原理next 表示后面有一个委托,每一层每一层套下去可以在任意的中间件来决定在后面的中间件之前执行什么,或者说在所有中间件执行完之后执行什么…

简单的二叉树创建与遍历

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后&…

疫情期间,千万级系统宕机N次,老板撂下狠话:没法把性提升10倍,全员解雇!...

性能调优整体思路作为一名团队技术核心,如何让系统跑得通、跑得稳、跑得快是必然会面对的场景。性能分析是一个大课题,不同的架构、不同的应用场景、不同的程序语言分析的方法若有差异,抽象一下大致分为两类:自底向上:…