一、主分析脚本(StatisticsNum.sh)如下

#!/bin/bash
echo "get cuurnt path"
basePath=$(cd $(dirname $0);pwd)
echo $basePath
cd $basePath

# define variables
# 统计起始时间
BEGIN_TIME=$1
# 统计截止时间
END_TIME=$2
#GitLab服务器分支存储默认路径,如有变更请同步修改
GITDATA_PATH="/var/opt/gitlab/git-data/repositories"

# 初始化相关路径
mkdir -p $basePath/report
mkdir -p $basePath/log

# 定义统计总天数函数(参数:起始日期、截止日期)
function CountEffectiveDays(){
  BEGIN_SECONDS=$(date -d "$1" "+%s")
  END_SECONDS=$(date -d "$2" "+%s")
  DIFF_SECONDS=$[$END_SECONDS-$BEGIN_SECONDS]
  expr $DIFF_SECONDS / 86400
}

# 定义计算时保留小数函数(参数:分子、分母、小数位数)
function KeepDecimal(){
  # 分子
  MEMBER=$1
  # 分母
  DENMOINATOR=$2
  # 小数位数
  DECIMAL_PLACES=$3
  cat $basePath/KeepDecimal.sh > $basePath/countfile.sh
  if [ ! -n "$DECIMAL_PLACES" ] ;then
	DNUMBER="2"
	echo "$AUTHOR DELETE IS NULL!"
  fi
  if  [ ! -n "$DECIMAL_PLACES" ] ;then
      DECIMAL_PLACES="2"
  fi
  sed -i "s#2#$DECIMAL_PLACES#g;" $basePath/countfile.sh
  # 更新表达式
  COUNTMET=$MEMBER/$DENMOINATOR
  sed -i "s#countmet#$COUNTMET#g;" $basePath/countfile.sh
  # 返回结果
  echo $( sh $basePath/countfile.sh)
  rm -rf $basePath/countfile.sh
}

# 计算统计总天数
TOTAL_DAYS=$( CountEffectiveDays $BEGIN_TIME $END_TIME )

# 定义记录日志函数
function logger(){
  printf "%s\n" "$*" >> $basePath/log/StatisticsNum.log
}

# define add message function
function ShowMessage(){
  echo "规则说明:"
  echo "提交次数:统计周期内用户提交commit的总次数"
  echo "日均提交:统计期内用户日均提交commit的次数"
  echo "文件:统计周期内文件累计修改总数"
  echo "变更:统计周期累计新增和修改总行数之和"
  echo "删除:统计周期内删除的总行数"
  echo "有效变更:统计周期内新增和变更的总行数"
  echo "日均变更:统计周期内日均有效变更行数"
  echo "变更度:变更/提交"
  echo "修改一行记作增加一行且删去一行"
  echo "merge操作内容不计入统计范围"
  echo "Statistics time [$BEGIN_TIME  $END_TIME)"
  echo "Statistics total days $TOTAL_DAYS"
  echo "Statistics total persons $TOTAL_PERSION"
}

# 文本转化格式化HTML函数(参数:名称 账号 提交次数 文件 变更 删除 有效变更 变更度 )
function HTMLFormat(){
  HTML_PATH="$basePath/report/RESULT.html"
  echo "<tr>" >> $HTML_PATH
  echo "<th align="center">$1</th>" >> $HTML_PATH
  echo "<th align="center">$2</th>" >> $HTML_PATH
  echo "<th align="center">$3</th>" >> $HTML_PATH
  echo "<th align="center" style="color:green">$4</th>" >> $HTML_PATH
  echo "<th align="center">$5</th>" >> $HTML_PATH
  echo "<th align="center">$6</th>" >> $HTML_PATH
  echo "<th align="center">$7</th>" >> $HTML_PATH
  echo "<th align="center">$8</th>" >> $HTML_PATH
  echo "<th align="center" style="color:green">$9</th>" >> $HTML_PATH
  echo "<th align="center">${10}</th>" >> $HTML_PATH
  echo "</tr>" >> $HTML_PATH
}

echo "get contents and subdirectory path"
cd $GITDATA_PATH
# 1.遍历GitLab服务器全部可用群组
for file in $GITDATA_PATH/*
do
    if test -f $file
    then
        echo "$file is a file"
    else
        echo $file
		cd $file
		# 2.遍历群组下的全部库
		for sonfile in $file/*
        do
            if test -f $sonfile
            then
                echo "$sonfile is a file"
            else
				cd $sonfile
				# 3.遍历不同库下的全部分支
				git branch -a | sed 's/.//' | sed -e 's/^/pre /' | awk -F" " '{print $2}' | while read BRANCHNAME
                do
                     # 获取单分支的相关使用信息源数据
				     echo $BRANCHNAME
				     # 获取有效用户列表
				     git log $BRANCHNAME --no-merges --pretty=format:"%ai,%cn:%s" --since="$BEGIN_TIME" --until="$END_TIME" | \
					     awk -F"," '{print $2}' | \
						 awk -F":" '{print $1}' > $basePath/USERLIST
				     # 4.遍历该分支下每个用户的提交信息
				     sort $basePath/USERLIST | uniq | while read USER
                     do
				         # 5.获取并格式化汇总元数据
				         git log $BRANCHNAME --no-merges --author="$USER"  --stat  --since="$BEGIN_TIME" --until="$END_TIME" | \
						     grep changed | \
							 awk '/insertion|deletion/' | \
							 while read LINE
				             do
				                 echo "$USER $LINE" >> $basePath/CollectMetadata
				                 echo "时间:$(date "+%Y.%m.%d-%H.%M.%S");库:$sonfile;分支:$BRANCHNAME;用户:$USER;单次源日志:$LINE;" >> $basePath/log/StatisticsNum.log
				             done
                     done
                done
            fi
        done
    fi
	logger "Run by user " $(id -un) "at " $(/bin/date)
done

echo "information Statistics And Generate RESULT"
# 添加表头信息
echo "名称 账号 提交次数 日均提交 文件 变更 删除 有效变更 日均变更 变更度" > $basePath/report/RESULT

# HTML格式化头
echo "<table border="1">" > $basePath/report/RESULT.html
HTMLFormat 名称 账号 提交次数 日均提交 文件 变更 删除 有效变更 日均变更 变更度

# 遍历获取有效用户列表
cat $basePath/CollectMetadata | awk '{print $1}' | sort | uniq | while read USER
do
    # 获取用户修改文件数
    FILESSUM=$( cat $basePath/CollectMetadata | grep -w $USER | awk '{print $2}' | awk '{sum+=$1}END{print sum}' )
	# 获取用户名称
    USER_NAME=$( cat $basePath/userlist | grep -w $USER | awk '{print $2}' | head -1 )
	if [ ! -n "$USER_NAME" ] ;then
	   USER_NAME="已清除账号"
    fi
    # 获取用户变更代码总行数
    INSERTIONSSUM=$( cat $basePath/CollectMetadata | grep -w $USER | awk -F"insertion" '{print $1}'| awk -F"," '{print $2}' | awk '{sub(/^[ \t]+/,"");print $0}' | awk '{sum+=$1}END{print sum}' )
    # 获取用户删除代码总行数
    DELETIONSSUM=$( cat $basePath/CollectMetadata | grep -w $USER | awk -F"," '{print $NF}' | awk -F"deletion" '{print $1}' | grep -v insertion | awk '{sub(/^[ \t]+/,"");print $0}' | awk '{sum+=$1}END{print sum}' )
    # 获取用户提交总次数
    COMMITNUM=$( cat $basePath/CollectMetadata | grep -w $USER | awk '{a[$1]++}END{for(i in a){print i,a[i] | "sort -r -k 2"}}' | sort -n -b -t" " -r -k2 | awk '{print $2}' )
    # 美化数据,将空值填充为o
    if [ ! -n "$FILESSUM" ] ;then
      FILESSUM="0"
      echo "$USER FILESSUM IS NULL!"
    fi
    if [ ! -n "$INSERTIONSSUM" ] ;then
      INSERTIONSSUM="0"
      echo "$USER INSERTIONSSUM IS NULL!"
    fi
    if [ ! -n "$DELETIONSSUM" ] ;then
      DELETIONSSUM="0"
      echo "$USER DELETIONSSUM IS NULL!"
    fi
	# 计算日均提交次数
	PREDAY_CNUMBER=$( KeepDecimal $COMMITNUM $TOTAL_DAYS 2 )
	# 计算日均变更(日均变更=变更总数/统计总天数)
	PREDAY_Eff=$( KeepDecimal $INSERTIONSSUM $TOTAL_DAYS 3 )
    # 计算变更度(变更度=变更/提交次数)
	MET=$( KeepDecimal $INSERTIONSSUM $COMMITNUM 2 )
    # 归集生成最终结果文件
    echo "$USER_NAME $USER $COMMITNUM $PREDAY_CNUMBER $FILESSUM $INSERTIONSSUM $DELETIONSSUM $INSERTIONSSUM $PREDAY_Eff $MET" >> $basePath/report/RESULT
	HTMLFormat $USER_NAME $USER $COMMITNUM $PREDAY_CNUMBER $FILESSUM $INSERTIONSSUM $DELETIONSSUM $INSERTIONSSUM $PREDAY_Eff $MET
	logger "Run by user " $(id -un) "at " $(/bin/date)
done

# 获取总人数
TOTAL_ROWS=$( cat $basePath/report/RESULT | awk '{print $1}' | uniq | wc -l )
TOTAL_PERSION=$( expr $TOTAL_ROWS - 1 )
# HTML格式化尾
echo "</table>" >> $basePath/report/RESULT.html
echo "<p>(Statistics TOTAL $TOTAL_PERSION PERSIONS  )<br /></p>" >> $basePath/report/RESULT.html
echo "<p>Statistics time [$BEGIN_TIME  $END_TIME)<br /></p>" >> $basePath/report/RESULT.html
echo "<p>Statistics total days $TOTAL_DAYS<br /></p>" >> $basePath/report/RESULT.html

echo "clean up temp files"
cd $basePath
rm -rf CollectMetadata USERLIST

# 格式化展示最终统计分析数据
echo "--------------------------------- EXPLAIN MESSAGES --------------------------------"
ShowMessage
echo "-------------------------------- FORMAT SHOW  DATA --------------------------------"
column -t $basePath/report/RESULT
echo "-------------------------------- FORMAT SHOW  END ---------------------------------"

if [ $? -eq 0 ]; then
  echo "successed."
else
  echo "failed , please check this script ."
  exit 1
fi

二、计算保留变更度脚本(KeepDecimal.sh)内容如下:

#!/bin/bash
basePath=$(cd $(dirname $0);pwd)
cd $basePath

awk 'BEGIN{printf "%0.2f",countmet}'

三、将两个脚本拷贝到GitLab服务器的任意同一目录下

#userlist用户对应一览表
zhangsan	张三
lisi	李四
wangwu	王五

四、传参(开始时间、截止时间)运行脚本:

sh StatisticsNum.sh begintime endtime

-rw-rw-r-- 1 peizhi peizhi    95 12月 27 15:05 KeepDecimal.sh
drwxr-xr-x 2 root   root      31 12月 27 15:06 log
-rw-rw-r-- 1 peizhi peizhi   121 12月 27 15:05 README
drwxr-xr-x 2 root   root      39 12月 27 15:08 report
-rw-rw-r-- 1 peizhi peizhi  8443 12月 27 15:21 StatisticsNum.sh
-rw-rw-r-- 1 peizhi peizhi 13386 12月 27 15:05 userlist
[root@vm-ghxw-gitlab-h13-8 StatisticsNum]# sh StatisticsNum.sh 2021-12-1 2021-12-28

五、等待完成并展示结果即可

gitlab的统计面板 gitlab代码统计插件_数据分析