shell腳本實現git和svn統計log代碼行

實現的功能

git

根據傳入的三個參數:起始統計日期、結束統計日期、git倉庫地址。python

腳本統計的是git倉庫內的全部分支的log信息。git

腳本統計的是指定時間段內、每個提交人指定的git地址的全部分支裏的提交代碼行的新增狀況。swift

其中代碼行可分別統計出:新增的有效代碼行數、新增的空行數、新增的註釋行數。數組

而且腳本中還作了相應的提交歷史「去重」,避免了這種狀況:「某個分支是以其餘分支爲基礎拉出來的,因此會將其餘分支的git歷史log一併複製,致使log歷史重複了兩份」,在統計時會去重,屢次重複的git提交log只會算做一次提交。svn

 

svn

svn的統計方式與git有很大不一樣,svn要查看log不須要將代碼checkout到本地。this

svn的log命令最多隻能看出,某個時間段內什麼用戶在什麼版本號下修改了那些文件,url

至於具體的修改內容,須要結合diff命令對每個文件進行檢查。spa

 

有相關log統計需求的朋友能夠按照本身的須要修改後使用。scala

 

腳本內容

git

腳本佈置在jenkins的job上,須要提早傳入如下參數:code

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
相關文章
相關標籤/搜索