zoukankan      html  css  js  c++  java
  • shell脚本实现git和svn统计log代码行

    实现的功能

    git

    根据传入的三个参数:起始统计日期、结束统计日期、git仓库地址。

    脚本统计的是git仓库内的所有分支的log信息。

    脚本统计的是指定时间段内、每一个提交人指定的git地址的所有分支里的提交代码行的新增情况。

    其中代码行可分别统计出:新增的有效代码行数、新增的空行数、新增的注释行数。

    并且脚本中还做了相应的提交历史“去重”,避免了这种情况:“某个分支是以其他分支为基础拉出来的,所以会将其他分支的git历史log一并复制,导致log历史重复了两份”,在统计时会去重,多次重复的git提交log只会算作一次提交。

    svn

    svn的统计方式与git有很大不同,svn要查看log不需要将代码checkout到本地。

    svn的log命令最多只能看出,某个时间段内什么用户在什么版本号下修改了那些文件,

    至于具体的修改内容,需要结合diff命令对每一个文件进行检查。

    有相关log统计需求的朋友可以按照自己的需要修改后使用。

    脚本内容

    git

    脚本布置在jenkins的job上,需要提前传入以下参数:

    start_time(起始统计日期,格式为:xxxx-xx-xx xx:xx:xx)

    end_time(结束统计日期,格式为:xxxx-xx-xx xx:xx:xx)

    repo_url(git仓库地址,如:http://xxx.xxx.xxx.xxx/xxxxx/xxxxx.git

    #clone主分支
    git clone ${repo_url}
    #cd进主分支文件夹
    #拆分出url地址的最后一个路径,该路径是clone下来的文件夹名
    newurl=${repo_url%.git};
    array=(${newurl//// })  
    filename=${array[${#array[*]}-1]}
    cd ./$filename
    cat>>chash_array
    #循环切换各个分支
    git branch -r | 
    grep -v '->' |
    while read remote; 
        do
        #将一个分支拉下来
        git checkout "$remote";
        #遍历该分支在指定时间节点上的所有提交人
        git log  --format='%cn' --since="${start_time}" --until="${end_time}" | sort -u | while read name;
            do
            #遍历该提交人的所有提交hash码
            git log --format='%H' --committer="${name}" --since="${start_time}" --until="${end_time}" | while read chash;
                do
                #0表示当前chash不在总数组中
                flag=0
                while read line;
                do
                    if [ $line = ${chash} ];then
                    flag=1
                    break
                    fi
                done < chash_array
                #如果当前chash值在其中,则不进行log统计,否则将该chash存入总数组,并统计该chash的log
                if [ ${flag} -eq 0 ];then
                    #将chash存入文件
                    echo $chash>>chash_array
                    #计算三种该chash的三种代码行数
                    num_null=`git show ${chash} | awk '/^+s*$/' | wc -l`;
                    num_ann=`git show ${chash} | awk '/^+s*/|^+s**|^+s*#|^+s*<!--|^+s*-->/' | wc -l`;
                    num_all=`git show ${chash} | awk '/^+/' | wc -l`;
                    num_code=$(($num_all-$num_null-$num_ann))
                    #以下开始为有效代码行赋权值,weight为1表示权值是1,为2表示权值是1.1,为3表示权值是1.3,为4表示权值是1.5
                    weight=1
                    this_file=`git show ${chash} | awk '/diff.*.js$/' | wc -l`;
                    if [ $this_file -ne 0 ]; then
                        weight=2
                    else
                        this_file=`git show ${chash} | awk '/diff.*.py$|diff.*.cpp$|diff.*.c$|diff.*.h$|diff.*.go$|diff.*.m$|diff.*.swift$/' | wc -l`;
                        if [ $this_file -ne 0 ]; then
                            weight=3
                        else
                            this_file=`git show ${chash} | awk '/diff.*.scala$/' | wc -l`;
                            if [ $this_file -ne 0 ]; then
                                weight=4
                            fi
                        fi
                    fi
                    #将所有参数传给python脚本
                    
                fi
            done
        done
        echo "下一个分支"
    done

    svn

    需提前传入以下参数:

    start_time(起始统计日期,格式为:xxxx-xx-xx xx:xx:xx)

    end_time(结束统计日期,格式为:xxxx-xx-xx xx:xx:xx)

    trunk_repo_id(trunk仓库id号)

    trunk_url(trunk仓库地址,如:svn://xxx.xxx.xxx.xxx/项目名/xxx/trunk)

    branches_repo_id(branches仓库id号)

    branches_url(branch仓库地址,如:svn://xxx.xxx.xxx.xxx/项目名/xxx/branches)

    # 1表示当前行内容为“用户名、版本号”。2表示当前行内容为“该版本的某一个被修改了的文件的路径”
    dothings=''
    #当前正在统计的用户的用户名
    username=''
    #当前正在统计的版本号
    rversion=''
    #拼接出文件路径的前缀
    OLD_IFS="$IFS" 
    IFS="/" 
    arr=($trunk_url) 
    IFS="$OLD_IFS"
    urlpre="svn://""${arr[2]}""/""${arr[3]}""/"
    #将需要查询的svn仓库地址装入数组
    svn_url_arr=("${trunk_url} ${trunk_repo_id}" "${branches_url} ${branches_repo_id}")
    
    for i in "${svn_url_arr[@]}" ; 
    do
        one=($i)
        now_url=${one[0]}
        repo_id=${one[1]}
        svn log -v -r {"$start_time"}:{"$end_time"} ${now_url} | while read line
        do
        if [ "${line}" = "------------------------------------------------------------------------" ]; 
        #如果当前行到这行,表示接下来该正则用户名与版本号了。
        then
            dothings='1'
        elif [ "${line}" = "Changed paths:" ]; 
        #如果当前行到这行,表示接下来该正则文件路径了
        then
            dothings='2'
        elif [ ${dothings} = '1' ]; 
        #正则出当前行的用户名和版本号,并赋值
        then
            OLD_IFS="$IFS" 
            IFS="|" 
            arr=($line) 
            IFS="$OLD_IFS"
            rversion=${arr[0]#r}
            username=${arr[1]}
        elif [ ${dothings} = '2' ];
        #正则当前行并拼接出路径,然后diff
        then
            fileurl=`echo ${line} | awk '//.*..*/'`
            #如果不为空,则表示文件格式正确,开始diff该文件详情
            if [ -n "$fileurl" ]; then
                OLD_IFS="$IFS" 
                IFS="(" 
                arr=($line) 
                IFS="$OLD_IFS"
                fileurl=${arr[0]#*/}
                fileurl="$urlpre""${fileurl}"
    
                svn diff -c $rversion ${fileurl}
                #计算该文件的三种代码行数
                num_null=`svn diff -c $rversion ${fileurl} | awk '/^+s*$/' | wc -l`;
                num_ann=`svn diff -c $rversion ${fileurl} | awk '/^+s*/|^+s**|^+s*#|^+s*<!--|^+s*-->/' | wc -l`;
                num_all=`svn diff -c $rversion ${fileurl} | awk '/^+/' | wc -l`;
                num_code=$(($num_all-$num_null-$num_ann-1))
    
                #以下开始为有效代码行赋权值,weight为1表示权值是1,为2表示权值是1.1,为3表示权值是1.3,为4表示权值是1.5
                weight=1
                this_file=`svn diff -c $rversion ${fileurl} | awk '/+++.*.js/' | wc -l`;
                if [ $this_file -ne 0 ]; then
                    weight=2
                else
                    this_file=`svn diff -c $rversion ${fileurl} | awk '/+++.*.py|+++.*.cpp|+++.*.c|+++.*.h|+++.*.go|+++.*.m|+++.*.swift/' | wc -l`;
                    if [ $this_file -ne 0 ]; then
                        weight=3
                    else
                        this_file=`svn diff -c $rversion ${fileurl} | awk '/+++.*.scala/' | wc -l`;
                        if [ $this_file -ne 0 ]; then
                            weight=4
                        fi
                    fi
                fi
    
                #将所有参数传给python脚本
    
            fi
        fi
        done
    done
  • 相关阅读:
    一个很老的故事: 水和鱼的故事
    签到
    WEBPART结合实际的应用(.Net2005)
    Silverlight 3正式版新鲜出炉
    一个端口扫描的小程序
    带验证功能的的TextBox
    php解析url并得到url中的参数及获取url参数的四种方式
    Mysql外键约束设置使用方法
    require(): open_basedir restriction in effect. 解决方法
    PHP将变量存储在数据库中,读取并执行变量的方法
  • 原文地址:https://www.cnblogs.com/red-code/p/9803673.html
Copyright © 2011-2022 走看看