2023年12月16日
By: Chase

写个shell脚本跑git统计

前言

公司钉钉周报要跑git统计的命令, 上报本周的commit数, commit行数, 我要跑3个命令, 分别修改日期跑了再复制粘贴, 挺烦. 写个shell文件直接跑了复制丢钉钉里行了.

备注: 本blog为mac环境, linux 与 win脚本命令会有差异.

命令与解释说明

统计自从某个时间段之后的commit信息

比如我要列出今年截止到今天的提交, 命令如下:

git log --after="2024-01-01 00:00:00" --pretty=format:"%s" --author="chase" 

结果: 图-0

说明:

--after是时间filter

--author是作者filter

--pretty=format:"%s"是格式处理, 这里选用了只过滤commit.

统计阶段内项目个人贡献次数

git log --after="2024-01-01 00:00:00" --author="chase" --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 20  

结果如下: 图-2

说明: --pretty='%aN'是按照作者名filter

下面几个都是sh对文本的处理:

| sort将输出传递给sort命令,按作者名字字母顺序排序

| uniq -c计算每个唯一作者名字的出现次数

| sort -k1 -n -r根据计数(-k1指定第一个字段,-n表示按数字排序,-r表示逆序)以数字降序排序计数

| head -n 20选择前20位贡献者,基于排序后的计数

可以像下图这样调试查看:

图-1

统计代码提交行数

git log --after="2024-01-01 00:00:00" --format='%aN' --author="chase" | sort -u | while read name; do echo -en "$name\t"; git log --after="$last_sunday_zero"  --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }'; done 

结果: 图-3

说明: 主要复杂在awk那段, 建议辅助shell的awk的文档说明理解.

sh文件编写

脚本文件创建

新建一个文件, 保存命名为伟大周报.sh

#!/bin/bash
echo "我要跑git命令!"

让他有执行权限chmod +x ./伟大周报.sh, 后执行下看看

./伟大周报.sh

日期变量获取与赋值

既然是要计算本周的log, 那就是since上周日00:00:00. 脚本里添加:

# 计算上一个周末的日期
# 今天是本周的第几天, 0是sunday(也是上个周末距离今天的天数)
days_since_sunday=$(date +%w)

# 获取上一个周日的日期, 例子: date -v -3d
last_sunday=$(date -v -"$days_since_sunday"d +%Y-%m-%d);

# 拼接00:00:00 时间字符串
last_sunday_zero="$last_sunday 00:00:00"
echo "统计since日期: $last_sunday_zero"

脚本完成

#!/bin/bash

# 计算上一个周末的日期
# 今天是本周的第几天, 0是sunday(也是上个周末距离今天的天数)
days_since_sunday=$(date +%w) 

# 获取上一个周日的日期, 例子: date -v -3d
last_sunday=$(date -v -"$days_since_sunday"d +%Y-%m-%d);

# 拼接00:00:00 时间字符串
last_sunday_zero="$last_sunday 00:00:00"
echo "统计since日期: $last_sunday_zero"

# 如果传了路径参数就统计特定路径的, 否则统计默认路径
if [ -z $1 ]
then
    default_path=~/Documents/project/mechanical-testing/
else
    default_path=$1
fi

# 代码行数统计脚本
cd $default_path
git log --after="$last_sunday_zero" --format='%aN' --author="chase" | sort -u | while read name; do echo -en "$name\t"; git log --after="$last_sunday_zero"  --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }'; done 

# 换行
echo "-----------------------"

# 代码次数统计脚本
git log --after="$last_sunday_zero" --author="chase" --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 20  
echo "-----------------------"

# 统计个人log
git log --after="$last_sunday_zero" --pretty=format:"%s" --author="chase" 
echo "-----------------------"

# 高经理要的git log1
#git log --after="$last_sunday_zero" --name-status --author="chase" > info.haha
#echo "-----------------------"

# 高经理要的git log2
#git log --after="$last_sunday_zero"  -p --author="chase"  > diff.haha

结果如下: 图-4

Tags: shell git