4 # gitdiffbinstat - gets a git diff --shortstat-like output for changed binary files
5 # Copyright (C) 2012 Matthias Krüger
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 1, or (at your option)
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
21 # in order to avoid conflicts when starting the script twice, get unix time + nanoseconds and
22 # append them to the diffstat file
24 timestamp
=`date +%s%N`
27 diffstat
=/tmp
/gitdiffstat.
${timestamp}
29 # If no argument is given, print this how-to.
30 if [ -z "${obj}" ] ; then
31 echo "Usage: \"gitdiffbinstat [<commit/branch/tag/HEAD>]\""
32 echo "Make sure to be in a git repo!"
36 # Check if we are actually in a git repo
38 gitcheck
=`git tag |& awk 'match($0,/fatal:\ Not\ a\ git\ repository\ /) {print substr($0,RSTART,RLENGTH)}'`
39 if [ "${gitcheck}" ] ; then
40 echo "fatal: Not a git repository!"
41 echo "Make sure to be in a git repo!"
46 curbranch
=`git branch | awk '/^\*\ /' | sed -e 's/\*\ //'`
47 # get current rev hash
48 curcommit
=`git rev-parse HEAD`
49 # print what we compare with git diff
50 echo " ${obj} -> ${curbranch}"
51 echo " ${obj} -> ${curcommit}"
54 # ${PWD} = current directory we are in
56 gitrootdirpre
=`git rev-parse --show-toplevel`
57 # if we have a dir named "…·µ@", this part of the script will fail, but I think it's quite unlikely
58 # and yes, it's a hack
59 gitrootdir
=`echo -n ${gitrootdirpre} | tr "/" "…·µ@"`
60 pwd2
=`echo ${PWD} | tr "/" "…·µ@"`
61 dir
=`echo ${pwd2} | sed s/^${gitrootdir}// | tr "…·µ@" "/" | sed -e 's/^\//.\//'`
62 if [ -z "${dir}" ] ; then
65 echo " Recursively getting stat for path \"${dir}\" from repo root."
69 # get the actuall diff we are going to process
70 git
diff ${obj} --stat .
/ |
awk '/>/' > ${diffstat}
73 # If there are no changes, exit
74 checksum
=`cat ${diffstat} | wc -l`
75 if [ ${checksum} == 0 ] ; then
76 echo " No binary files changed, exiting..."
81 # generate our own git diff --shortstat
82 gst
=`git diff ${obj} --shortstat ./`
83 gstins
=`echo ${gst} | awk '{print $4}'`
84 gstdels
=`echo ${gst} | awk '{print $6}'`
85 gstchval
=`expr ${gstins} - ${gstdels}`
86 gstchfiles
=`echo ${gst} | awk '{print $1}'`
89 if [ "${gstchfiles}" == 1 ] ; then
94 # say file/files correctly if we have only 0, one or several files
95 if [ "${gstchval}" -gt 0 ] ; then
96 echo -e " ${gstchfiles} ${gstfiles} changed, \e[033;32m${gstins} \e[0minsertions(\e[033;32m+\e[0m), \e[033;31m${gstdels}\e[0m deletions(\e[033;31m-\e[0m) (\e[033;32m+${gstchval} lines\e[0m)"
98 echo -e " ${gstchfiles} ${gstfiles} changed, \e[033;32m${gstins} \e[0minsertions(\e[033;32m+\e[0m), \e[033;31m${gstdels}\e[0m deletions(\e[033;31m-\e[0m) (\e[033;31m${gstchval} lines\e[0m)"
103 # size (b) of all bin files of obj
104 old
=`awk '{ sum+=$4} END {print sum}' ${diffstat}`
105 # size (b) of all bin files of curbranch/curcommit
106 new
=`awk '{ sum+=$6} END {print sum}' ${diffstat}`
107 # amount of changed files
108 files
=`wc -l ${diffstat} | awk '{print $1}'`
113 # "Bin 0 -> x bytes" : file has been added
114 newfiles
=`awk '/Bin\ 0/' ${diffstat} | wc -l`
115 # "Bin x -> 0 bytes" : file has been deleted
116 delfiles
=`awk '/->\ 0\ bytes/' ${diffstat} | wc -l`
117 # all files - new files - deleted files = modified files
118 binchval
=`expr ${newfiles} - ${delfiles}`
119 chfiles
=`expr ${files} - ${binchval}`
121 if [ "${binchval}" -gt 0 ] ; then
122 echo -e " Binary files: ${chfiles} modified, \e[033;32m${newfiles}\e[0m added, \e[033;31m${delfiles}\e[0m deleted. (\e[033;32m+${binchval} files\e[0m)"
124 echo -e " Binary files: ${chfiles} modified, \e[033;32m${newfiles}\e[0m added, \e[033;31m${delfiles}\e[0m deleted. (\e[033;31m${binchval} files\e[0m)"
128 # find out how many bytes bigger/smaller the repo got
129 changeval
=`calc -p "${new}-${old}"`
130 # print the result in different colors :)
132 # say file/files correctly if we have only 0, one or several files
133 if [ "${files}" == 1 ] ; then
139 if [ "${changeval}" -gt 0 ] ; then
140 echo -e " ${files} binary ${somefiles} changed, \e[033;31m${old} bytes\e[0m -> \e[033;32m${new} bytes\e[0m (\e[033;32m+${changeval} bytes\e[0m)"
142 changeval1
=`echo "${changeval}" | sed s/-//`
143 echo -e " ${files} binary ${somefiles} changed, \e[033;31m${old} bytes\e[0m -> \e[033;32m${new} bytes\e[0m (\e[033;31m-${changeval1} bytes\e[0m)"
146 # rather ugly foo to get nicer output numbers
149 ((newkilo
=${new}/1024))
150 if [ ! "${newkilo}" == 0 ] ; then
153 ((newmega
=${newkilo}/1024))
154 if [ ! "${newmega}" == 0 ] ; then
157 ((newgiga
=${newmega}/1024))
158 if [ ! "${newgiga}" == 0 ] ; then
168 ((oldkilo
=${old}/1024))
169 if [ ! "${oldkilo}" == 0 ] ; then
172 ((oldmega
=${oldkilo}/1024))
173 if [ ! "${oldmega}" == 0 ] ; then
176 ((oldgiga
=${oldmega}/1024))
177 if [ ! "${oldgiga}" == 0 ] ; then
185 if [ "${changeval}" -gt 0 ] ; then
187 changevalval
=${changeval}
188 ((changevalkilo
=${changeval}/1024))
189 if [ ! "${changevalkilo}" == 0 ] ; then
191 changevalval
=${changevalkilo}
192 ((changevalmega
=${changevalkilo}/1024))
193 if [ ! "${changevalmega}" == 0 ] ; then
195 changevalval
=${changevalmega}
196 ((changevalgiga
=${changevalmega}/1024))
197 if [ ! "${changevalgiga}" == 0 ] ; then
199 changevalval
=${changvalgiga}
203 echo -e " ${files} binary ${somefiles} changed, \e[033;31m${oldval}${oldunit}\e[0m -> \e[033;32m${newval}${newunit}\e[0m (\e[033;32m+${changevalval}${changevalunit}\e[0m)"
206 changeval
=`echo "${changeval}" | sed s/-//`
208 changevalval
=${changeval}
209 ((changevalkilo
=${changeval}/1024))
210 if [ ! "${changevalkilo}" == 0 ] ; then
212 changevalval
=${changevalkilo}
213 ((changevalmega
=${changevalkilo}/1024))
214 if [ ! "${changevalmega}" == 0 ] ; then
216 changevalval
=${changevalmega}
217 ((changevalgiga
=${changevalmega}/1024))
218 if [ ! "${changevalgiga}" == 0 ] ; then
220 changevalval
=${changvalgiga}
224 echo -e " ${files} binary ${somefiles} changed, \e[033;31m${oldval} ${oldunit}\e[0m -> \e[033;32m${newval} ${newunit}\e[0m (\e[033;31m-${changevalval} ${changevalunit}\e[0m)"
227 # remove the diffstat, we don't need it anymore