]>
Commit | Line | Data |
---|---|---|
1cd48d7b JH |
1 | #!/bin/sh |
2 | # How much of the very original version from Linus survive? | |
3 | ||
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" | |
6 | ||
e7e5b124 JH |
7 | summary= |
8 | while case $# in 0) break ;; esac | |
9 | do | |
10 | case "$1" in | |
11 | -s | --summary) | |
12 | summary=t | |
13 | ;; | |
14 | -*) | |
15 | echo >&2 "$1: unknown option" | |
16 | exit 1 | |
17 | ;; | |
18 | *) | |
19 | break | |
20 | ;; | |
21 | esac | |
22 | shift | |
23 | done | |
24 | ||
25 | if test $# = 0 | |
26 | then | |
27 | this=HEAD | |
28 | else | |
29 | this=$1 | |
30 | shift | |
31 | fi | |
32 | ||
33 | if test $# = 0 | |
34 | then | |
35 | initial=e83c5163316f89bfbde7d9ab23ca2e25604af290 | |
36 | range="..$this" | |
37 | else | |
38 | initial=$1 | |
39 | range="$initial..$this" | |
40 | shift | |
41 | fi | |
42 | ||
43 | this=$(git rev-parse --verify "$this^0") && | |
44 | initial=$(git rev-parse --verify "$initial^0") || exit | |
1cd48d7b JH |
45 | |
46 | tmp="/var/tmp/Linus.$$" | |
47 | trap 'rm -f "$tmp".*' 0 | |
48 | ||
49 | # We blame each file in the initial revision pretending as if it is a | |
50 | # direct descendant of the given version, and also pretend that the | |
51 | # latter is a root commit. This way, lines in the initial revision | |
52 | # that survived to the other version can be identified (they will be | |
53 | # attributed to the other version). | |
54 | graft="$tmp.graft" && | |
55 | { | |
56 | echo "$initial $this" | |
57 | echo "$this" | |
58 | } >"$graft" || exit | |
59 | ||
60 | opts='-C -C -C -w' | |
61 | ||
62 | show () { | |
63 | s=$1 t=$2 n=$3 | |
64 | p=$(($s * 100 / $t)) | |
65 | c=$(($s * 10000 / $t - $p * 100)) | |
66 | printf "%12d %12d %s (%d.%02d%%)\n" $s $t $n $p $c | |
67 | } | |
68 | ||
e7e5b124 JH |
69 | empty_tree=$(git hash-object -t tree -w --stdin </dev/null) |
70 | ||
71 | git diff-tree -r --raw $empty_tree $initial -- "$@" | | |
72 | while read mode_old mode_new sha1_old sha1_new op name | |
1cd48d7b | 73 | do |
e7e5b124 | 74 | git blame $opts --porcelain -S "$graft" "$this..$initial" -- "$name" | |
1cd48d7b JH |
75 | sed -ne "s/^\($_x40\) .*/\1/p" | |
76 | sort | | |
77 | uniq -c | { | |
78 | # There are only two commits in the fake history, so | |
79 | # there will be at most two output from the above. | |
80 | read cnt1 commit1 | |
81 | read cnt2 commit2 | |
82 | if test -z "$commit2" | |
83 | then | |
84 | cnt2=0 | |
85 | fi | |
86 | if test "$initial" != "$commit1" | |
87 | then | |
88 | cnt_surviving=$cnt1 | |
89 | else | |
90 | cnt_surviving=$cnt2 | |
91 | fi | |
92 | cnt_total=$(( $cnt1 + $cnt2 )) | |
93 | echo "$cnt_surviving $cnt_total $name" | |
94 | } | |
95 | done | { | |
96 | total=0 | |
97 | surviving=0 | |
e7e5b124 | 98 | test -n "$summary" || |
1cd48d7b JH |
99 | printf "%12s %12s %s (survival%%)\n" surviving original path |
100 | while read s t n | |
101 | do | |
102 | total=$(( $total + $t )) surviving=$(( $surviving + $s )) | |
e7e5b124 | 103 | test -n "$summary" || |
1cd48d7b JH |
104 | show $s $t $n |
105 | done | |
e7e5b124 JH |
106 | if test -n "$summary" |
107 | then | |
108 | echo $surviving $total | |
109 | else | |
110 | label=Total | |
111 | show $surviving $total $label | |
112 | fi | |
113 | ||
1cd48d7b | 114 | } |