很多公司都要每周或者每个月统计代码提交量,我们一般都是进入指定仓库,然后执行git log
命令,这对于小公司,仓库很少的时候非常好用。但是有一些公司,组件化做的非常细,代码仓库几十个,这个时候我们在挨个仓库执行git log
命令就会很繁琐。这个时候我们就可以使用shell
脚本帮我们快速执行
git log 查询代码量
swift
git log --author="作者名" --after="2025-02-01 00:00:00" --before="2025-03-01 00:00:00" --pretty=tformat: --numstat | grep -v 'static' | awk '{ add += $1 ; subs += $2 ; loc += $1 - $2 ;sum += $1 + $2} END { printf "增加行数:%s 删除行数:%s 变化总行数:%s 增删总数:%s\n",add,subs,loc,sum}'
这段代码的主要功能是统计指定作者在特定时间范围内提交的代码行数变化情况,并且会排除与 static
相关的文件变更记录。具体统计的指标包括增加行数、删除行数、变化总行数(增加行数与删除行数之和)以及增删总数(增加行数减去删除行数)。
git log
部分
ini
git log --author="作者名" --after="2025-02-01 00:00:00" --before="2025-03-01 00:00:00" --pretty=tformat: --numstat
--author="作者名"
:指定只统计作者为作者名
的提交记录。--after="2025-02-01 00:00:00"
和--before="2025-03-01 00:00:00"
:限定提交记录的时间范围,只统计 2025 年 2 月 1 日 0 点到 2025 年 3 月 1 日 0 点之间的提交。--pretty=tformat:
:不输出提交的描述信息,只保留--numstat
输出的统计信息。--numstat
:为每个提交输出文件级别的统计信息,每行包含三个字段,分别是增加的行数、删除的行数和文件路径。
grep -v 'static'
部分
perl
grep -v 'static'
-v
选项表示反向匹配,即过滤掉包含static
字符串的行。这一步的作用是排除与static
相关的文件变更记录,只统计其他文件的代码行数变化。
awk
部分
swift
awk '{ add += $1 ; subs += $2 ; loc += $1 - $2 ;sum += $1 + $2} END { printf "增加行数:%s 删除行数:%s 变化总行数:%s 增删总数:%s\n",add,subs,loc,sum}'
{ add += $1 ; subs += $2 ; loc += $1 - $2 ;sum += $1 + $2}
:对于每一行输入,将第一个字段(增加的行数)累加到变量add
中,将第二个字段(删除的行数)累加到变量subs
中,计算增加行数与删除行数的差值并累加到变量loc
中,计算增加行数与删除行数的和并累加到变量sum
中。END { printf "增加行数:%s 删除行数:%s 变化总行数:%s 增删总数:%s\n",add,subs,loc,sum}
:在处理完所有输入行后,使用printf
函数输出统计结果,包括增加行数、删除行数、变化总行数和增删总数。
shell脚本统计文件夹下面的代码提交量
bash
#!/bin/bash
# 定义时间范围
start_date="2025-01-01"
end_date="2025-03-01"
# 目标文件夹路径
target_folder="/path/to/your/folder"
# 指定作者
author="指定作者"
# 初始化总统计数据
total_added=0
total_deleted=0
total_changed=0
total_net=0
# 打印时间范围信息
echo "统计时间范围:从 $start_date 到 $end_date"
echo "指定作者:$author"
echo "---------------------"
# 进入目标文件夹
cd "$target_folder"
# 遍历每个子文件夹
for repo in */; do
# 检查是否为 Git 仓库
if [ -d "$repo/.git" ]; then
# 统计指定时间范围内、指定作者的代码行数变化,排除合并提交
stats=$(cd "$repo" && git log --author="$author" --numstat --since="$start_date" --until="$end_date" --no-merges | awk 'NF==3 {plus+=$1; minus+=$2} END {print plus, minus, plus + minus, plus - minus}')
# 分割统计结果
read -r added_lines deleted_lines changed_lines net_lines <<< "$stats"
# 检查变量是否为空,如果为空则赋值为 0
if [ -z "$changed_lines" ]; then
changed_lines=0
fi
if [ -z "$added_lines" ]; then
added_lines=0
fi
if [ -z "$deleted_lines" ]; then
deleted_lines=0
fi
if [ -z "$net_lines" ]; then
net_lines=0
fi
# 过滤掉变化总行数为 0 的仓库
if [ "$changed_lines" -ne 0 ]; then
# 输出仓库名称和统计信息
echo "仓库:$(basename "$repo")"
echo " 增加行数:$added_lines"
echo " 删除行数:$deleted_lines"
echo " 变化总行数:$changed_lines"
echo " 增删总数:$net_lines"
# 累加总统计数据
total_added=$((total_added + added_lines))
total_deleted=$((total_deleted + deleted_lines))
total_changed=$((total_changed + changed_lines))
total_net=$((total_net + net_lines))
fi
fi
done
# 输出总统计数据
echo "---------------------"
echo "总统计信息:"
echo " 总增加行数:$total_added"
echo " 总删除行数:$total_deleted"
echo " 总变化总行数:$total_changed"
echo " 总增删总数:$total_net"
代码详细解析
1. 定义变量
ini
#!/bin/bash
# 定义时间范围
start_date="2025-01-01"
end_date="2025-03-01"
# 目标文件夹路径
target_folder="/path/to/your/folder"
# 指定作者
author="指定作者"
# 初始化总统计数据
total_added=0
total_deleted=0
total_changed=0
total_net=0
#!/bin/bash
:指定脚本使用 Bash 解释器执行。start_date
和end_date
:定义统计的时间范围。target_folder
:指定包含多个 Git 仓库的目标文件夹路径。author
:指定要统计的代码作者。total_added
、total_deleted
、total_changed
和total_net
:分别用于存储所有仓库的总增加行数、总删除行数、总变化总行数和总增删总数,初始值都为 0。
2、进入目标文件夹
bash
# 进入目标文件夹
cd "$target_folder"
3、遍历子文件夹并统计代码变化
bash
# 遍历每个子文件夹
for repo in */; do
# 检查是否为 Git 仓库
if [ -d "$repo/.git" ]; then
# 统计指定时间范围内、指定作者的代码行数变化,排除合并提交
stats=$(cd "$repo" && git log --author="$author" --numstat --since="$start_date" --until="$end_date" --no-merges | awk 'NF==3 {plus+=$1; minus+=$2} END {print plus, minus, plus + minus, plus - minus}')
# 分割统计结果
read -r added_lines deleted_lines changed_lines net_lines <<< "$stats"
# 检查变量是否为空,如果为空则赋值为 0
if [ -z "$changed_lines" ]; then
changed_lines=0
fi
if [ -z "$added_lines" ]; then
added_lines=0
fi
if [ -z "$deleted_lines" ]; then
deleted_lines=0
fi
if [ -z "$net_lines" ]; then
net_lines=0
fi
# 过滤掉变化总行数为 0 的仓库
if [ "$changed_lines" -ne 0 ]; then
# 输出仓库名称和统计信息
echo "仓库:$(basename "$repo")"
echo " 增加行数:$added_lines"
echo " 删除行数:$deleted_lines"
echo " 变化总行数:$changed_lines"
echo " 增删总数:$net_lines"
# 累加总统计数据
total_added=$((total_added + added_lines))
total_deleted=$((total_deleted + deleted_lines))
total_changed=$((total_changed + changed_lines))
total_net=$((total_net + net_lines))
fi
fi
done
-
for repo in */; do ... done
:遍历目标文件夹下的所有子文件夹。 -
if [ -d "$repo/.git" ]; then ... fi
:检查当前子文件夹是否为 Git 仓库,通过判断是否存在.git
文件夹来确定。
perl
stats=$(cd "$repo" && git log --author="$author" --numstat --since="$start_date" --until="$end_date" --no-merges | awk 'NF==3 {plus+=$1; minus+=$2} END {print plus, minus, plus + minus, plus - minus}')
:
-
cd "$repo"
:进入当前 Git 仓库。 -
git log --author="$author" --numstat --since="$start_date" --until="$end_date" --no-merges
:获取指定作者在指定时间范围内(排除合并提交)的提交记录,并以--numstat
格式输出,该格式会显示每个文件的增加行数和删除行数。 -
awk 'NF==3 {plus+=$1; minus+=$2} END {print plus, minus, plus + minus, plus - minus}'
:使用awk
脚本对git log
的输出进行处理,统计增加行数、删除行数、变化总行数和增删总数。 -
read -r added_lines deleted_lines changed_lines net_lines <<< "$stats"
:将stats
变量的值分割为四个变量,分别存储增加行数、删除行数、变化总行数和增删总数。 -
if [ -z "$changed_lines" ]; then ... fi
:检查变量是否为空,如果为空则将其赋值为 0。 -
if [ "$changed_lines" -ne 0 ]; then ... fi
:过滤掉变化总行数为 0 的仓库,只处理有代码变化的仓库。 -
echo "仓库:$(basename "$repo")"
:输出当前仓库的名称。 -
total_added=$((total_added + added_lines))
等:累加当前仓库的统计数据到总统计数据中