1 | #!/bin/sh
|
2 | #- Usage: stat [heatmap|commit|files|style|all|short] [src..]
|
3 |
|
4 | # TODO:2018-03-16:lauri:Rewrite to Javascript
|
5 |
|
6 | TYPE="short"
|
7 |
|
8 | case "$1" in heatmap|commit|files|style|all|short)
|
9 | TYPE=$1
|
10 | shift;;
|
11 | esac
|
12 |
|
13 | count() {
|
14 | sort | uniq -c | sort ${1-"-nr"}
|
15 | }
|
16 |
|
17 | ranges() {
|
18 | sed -e 's/0[789]$\|1[0-4]$/07-14/' \
|
19 | -e 's/1[5-9]$\|2[012]$/15-22/' \
|
20 | -e 's/0[0-6]$\|23$/23-06/'
|
21 | }
|
22 |
|
23 | table() {
|
24 | awk -vx="$1" 'BEGIN{sum=0}NF>0{sum+=a[++c]=$1;sub(" *"$1"[\t ]*","");t[c]=$0}END{printf "\n%s: %s\n\n",x,sum;for(;++i<=c;)printf "%6s %3i%% %s\n",a[i],100*a[i]/sum,t[i]}'
|
25 | }
|
26 |
|
27 | countBlame() {
|
28 | xargs -I{} -0 -n1 git blame -w --line-porcelain "{}" | \
|
29 | grep '^author \|^ ' | \
|
30 | grep -B 1 '^ .*[^[:space:]]' | \
|
31 | sed -n 's/^author //p' | \
|
32 | count | table "$1"
|
33 | }
|
34 |
|
35 | printf "Working directory: %s\n" "$(du -hs --exclude=.git "$@")"
|
36 |
|
37 | printf "Git directory: %s\n" "$(du -hs .git)"
|
38 |
|
39 | printf "Number of developers: %s\n" "$(git shortlog -s -- "$@" | wc -l)"
|
40 |
|
41 |
|
42 |
|
43 | git shortlog -sen -- "$@" | \
|
44 | table "Number of commits"
|
45 |
|
46 | git grep -IlHz '[^[:space:]]' -- "$@" | \
|
47 | countBlame "Number of non-blank lines"
|
48 |
|
49 | git log --format='%ai %aN <%aE>' -- "$@" | cut -c1-10,26- | sort -u | cut -c11- | \
|
50 | count | table "Number of dates when commited"
|
51 |
|
52 | git log --format='%ai %aN <%aE>' -- "$@" | cut -c1-13,26- | sort -u | cut -c15- | \
|
53 | count | table "Number of hours when commited"
|
54 |
|
55 | (git grep -l '' -- "$@"; git grep -Il '' -- "$@") | sort | uniq -u | awk -F '[/.]' '{print $NF}' | \
|
56 | count | table "Number of binary files"
|
57 |
|
58 | git grep -Il '' -- "$@" | awk -F '[/.]' '{print $NF}' | \
|
59 | count | table "Number of text files"
|
60 |
|
61 | textFiles=$(git grep -IHz '[^[:space:]]' -- "$@" | awk -F'\x00' '{sub(".*\\.","",$1);print $1}' | count)
|
62 |
|
63 | echo "$textFiles" | table "Number of non-blank lines"
|
64 |
|
65 |
|
66 | case "$TYPE" in files|all)
|
67 | echo "$textFiles" | while read num ext; do
|
68 | git ls-files -zi -x "*.$ext" -x "*/$ext" -- "$@" | \
|
69 | countBlame "Non-blank lines of $ext"
|
70 | done
|
71 | ;;
|
72 | esac
|
73 |
|
74 |
|
75 | case "$TYPE" in heatmap|all)
|
76 | log=$(git log --format="%ai %aD" -- "$@")
|
77 | echo "$log" | cut -c12-13 | \
|
78 | count "-n -k2" | table "Number of commits in hour"
|
79 |
|
80 | echo "$log" | cut -c12-13 | ranges | \
|
81 | count "-n -k2" | table "Number of commits in hour range"
|
82 |
|
83 | echo "$log" | cut -c27-29 | \
|
84 | count | table "Number of commits in weekday"
|
85 |
|
86 | echo "$log" | cut -c1-13 | sort -u | cut -c12-13 | \
|
87 | count "-n -k2" | table "Number of dates commited in hour"
|
88 |
|
89 | echo "$log" | cut -c1-13 | sort -u | cut -c12-13 | ranges | \
|
90 | count "-n -k2" | table "Number of dates commited in hour range"
|
91 |
|
92 | echo "$log" | cut -c1-11,27-29 | sort -u | cut -c12-14 | \
|
93 | count | table "Number of dates commited in weekday"
|
94 | ;;
|
95 | esac
|
96 |
|
97 |
|
98 | case "$TYPE" in commit|all)
|
99 | git log --shortstat --format="" -- "$@" | cut -d, -f1 | \
|
100 | count | table "Number of files changed by commit"
|
101 |
|
102 | git log --shortstat --format="" -- "$@" | \
|
103 | awk '{print 10^int(log($4+$6)/log(10))}' | \
|
104 | count "-n -k2" | table "Number of lines written by commit"
|
105 | ;;
|
106 | esac
|
107 |
|
108 | case "$TYPE" in style|all)
|
109 | git grep -Ih "" -- "$@" | awk '{print 10^int(log(length())/log(10))}' | \
|
110 | count "-n -k2" | table "Line lenghts"
|
111 |
|
112 | ;;
|
113 | esac
|
114 |
|
115 | exit 0
|
116 |
|
117 | REPOS=$2
|
118 |
|
119 | log() {
|
120 | if [ -n "$REPOS" ]; then
|
121 | for REPO in $REPOS; do
|
122 | (cd $REPO && git log $1)
|
123 | done
|
124 | else
|
125 | git log $1
|
126 | fi
|
127 | }
|
128 |
|
129 | # $ git rev-list -n 1 --before="2014-10-24 00:00" devel
|
130 | # git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`
|
131 |
|
132 |
|
133 | # $ git checkout 'master@{1979-02-26 18:30:00}'
|
134 | # will not work, because it uses the reflog (which expires after some time).
|
135 |
|
136 | # Number of commits in work time by hour
|
137 | # git log --format="%ai %aD" | cut -c12-13,26-29 | sed -e 's/^0[89]\|^1[0-7]/08-17/' -e 's/^[012][0-9] /18-07 /' | sort | uniq -c | sort -nr
|
138 | # Number of commits in work time
|
139 | # git log --format="%ai %aD" | cut -c12-13,26-29 | sed -e 's/^\(0[89]\|1[0-7]\) \(Mon\|Tue\|Wed\|Thu\|Fri\)/08-17 in week/' -e 's/^[012][0-9] .*/18-07 or weekend/' | sort | uniq -c | sort -nr
|
140 | # Number of dates in work time
|
141 | # git log --format="%ai %aD" | cut -c1-13,26-29 | sed -e 's/ \(0[89]\|1[0-7]\) \(Mon\|Tue\|Wed\|Thu\|Fri\)/ 08-17 in week/' -e 's/ [012][0-9] .*/ 18-07 or weekend/' | sort -u | cut -c12- | sort | uniq -c | sort -nr
|
142 | # Line lenghts
|
143 | # git grep -Ih "" | awk '{print 10^int(log(length())/log(10))}' | sort | uniq -c | sort -n -k2
|
144 |
|
145 |
|
146 | #echo "RUN $0 $*"
|
147 |
|
148 | ranges() {
|
149 | sed -e 's/0[789]$\|1[0-4]$/07-14/' \
|
150 | -e 's/1[5-9]$\|2[012]$/15-22/' \
|
151 | -e 's/0[0-6]$\|23$/23-06/'
|
152 | # sed -e 's/0[2-7]$/02-07/' \
|
153 | # -e 's/0[89]$\|1[0-3]$/08-13/' \
|
154 | # -e 's/1[4-9]$/14-19/' \
|
155 | # -e 's/0[01]$\|2.$/20-01/'
|
156 | }
|
157 |
|