What's cooking (2013/01 #11)
[alt-git.git] / Linus
blob8cbcd18bb71e6dbbad52f84106128ef066a4ff5f
1 #!/bin/sh
2 # How much of the very original version from Linus survive?
4 _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
5 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
7 initial=$(git rev-parse --verify e83c5163316f89bfbde7d9ab23ca2e25604af290) &&
8 this=$(git rev-parse --verify ${1-HEAD}^0) || exit
10 tmp="/var/tmp/Linus.$$"
11 trap 'rm -f "$tmp".*' 0
13 # We blame each file in the initial revision pretending as if it is a
14 # direct descendant of the given version, and also pretend that the
15 # latter is a root commit. This way, lines in the initial revision
16 # that survived to the other version can be identified (they will be
17 # attributed to the other version).
18 graft="$tmp.graft" &&
20 echo "$initial $this"
21 echo "$this"
22 } >"$graft" || exit
24 opts='-C -C -C -w'
26 show () {
27 s=$1 t=$2 n=$3
28 p=$(($s * 100 / $t))
29 c=$(($s * 10000 / $t - $p * 100))
30 printf "%12d %12d %s (%d.%02d%%)\n" $s $t $n $p $c
33 git ls-tree -r "$initial" |
34 while read mode type sha1 name
36 git blame $opts --porcelain -S "$graft" "$initial" -- "$name" |
37 sed -ne "s/^\($_x40\) .*/\1/p" |
38 sort |
39 uniq -c | {
40 # There are only two commits in the fake history, so
41 # there will be at most two output from the above.
42 read cnt1 commit1
43 read cnt2 commit2
44 if test -z "$commit2"
45 then
46 cnt2=0
48 if test "$initial" != "$commit1"
49 then
50 cnt_surviving=$cnt1
51 else
52 cnt_surviving=$cnt2
54 cnt_total=$(( $cnt1 + $cnt2 ))
55 echo "$cnt_surviving $cnt_total $name"
57 done | {
58 total=0
59 surviving=0
60 printf "%12s %12s %s (survival%%)\n" surviving original path
61 while read s t n
63 total=$(( $total + $t )) surviving=$(( $surviving + $s ))
64 # printf "%12d %12d %s\n" $s $t $n
65 show $s $t $n
66 done
67 # printf "%12d %12d %s\n" $surviving $total Total
68 show $surviving $total Total