]> git.ipfire.org Git - thirdparty/git.git/blame - Linus
What's cooking (2023/08 #04)
[thirdparty/git.git] / Linus
CommitLineData
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
7summary=
8while case $# in 0) break ;; esac
9do
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
23done
24
25if test $# = 0
26then
27 this=HEAD
28else
29 this=$1
30 shift
31fi
32
33if test $# = 0
34then
35 initial=e83c5163316f89bfbde7d9ab23ca2e25604af290
36 range="..$this"
37else
38 initial=$1
39 range="$initial..$this"
40 shift
41fi
42
43this=$(git rev-parse --verify "$this^0") &&
44initial=$(git rev-parse --verify "$initial^0") || exit
1cd48d7b
JH
45
46tmp="/var/tmp/Linus.$$"
47trap '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).
54graft="$tmp.graft" &&
55{
56 echo "$initial $this"
57 echo "$this"
58} >"$graft" || exit
59
60opts='-C -C -C -w'
61
62show () {
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
69empty_tree=$(git hash-object -t tree -w --stdin </dev/null)
70
71git diff-tree -r --raw $empty_tree $initial -- "$@" |
72while read mode_old mode_new sha1_old sha1_new op name
1cd48d7b 73do
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 }
95done | {
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}