Merge branch 'jc/fsync-can-fail-with-eintr'
[git] / contrib / coverage-diff.sh
1 #!/bin/sh
2
3 # Usage: Run 'contrib/coverage-diff.sh <version1> <version2>' from source-root
4 # after running
5 #
6 #     make coverage-test
7 #     make coverage-report
8 #
9 # while checked out at <version2>. This script combines the *.gcov files
10 # generated by the 'make' commands above with 'git diff <version1> <version2>'
11 # to report new lines that are not covered by the test suite.
12
13 V1=$1
14 V2=$2
15
16 diff_lines () {
17         perl -e '
18                 my $line_num;
19                 while (<>) {
20                         # Hunk header?  Grab the beginning in postimage.
21                         if (/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/) {
22                                 $line_num = $1;
23                                 next;
24                         }
25
26                         # Have we seen a hunk?  Ignore "diff --git" etc.
27                         next unless defined $line_num;
28
29                         # Deleted line? Ignore.
30                         if (/^-/) {
31                                 next;
32                         }
33
34                         # Show only the line number of added lines.
35                         if (/^\+/) {
36                                 print "$line_num\n";
37                         }
38                         # Either common context or added line appear in
39                         # the postimage.  Count it.
40                         $line_num++;
41                 }
42         '
43 }
44
45 files=$(git diff --name-only "$V1" "$V2" -- \*.c)
46
47 # create empty file
48 >coverage-data.txt
49
50 for file in $files
51 do
52         git diff "$V1" "$V2" -- "$file" |
53         diff_lines |
54         sort >new_lines.txt
55
56         if ! test -s new_lines.txt
57         then
58                 continue
59         fi
60
61         hash_file=$(echo $file | sed "s/\//\#/")
62
63         if ! test -s "$hash_file.gcov"
64         then
65                 continue
66         fi
67
68         sed -ne '/#####:/{
69                         s/    #####://
70                         s/:.*//
71                         s/ //g
72                         p
73                 }' "$hash_file.gcov" |
74         sort >uncovered_lines.txt
75
76         comm -12 uncovered_lines.txt new_lines.txt |
77         sed -e 's/$/\)/' |
78         sed -e 's/^/ /' >uncovered_new_lines.txt
79
80         grep -q '[^[:space:]]' <uncovered_new_lines.txt &&
81         echo $file >>coverage-data.txt &&
82         git blame -s "$V2" -- "$file" |
83         sed 's/\t//g' |
84         grep -f uncovered_new_lines.txt >>coverage-data.txt &&
85         echo >>coverage-data.txt
86
87         rm -f new_lines.txt uncovered_lines.txt uncovered_new_lines.txt
88 done
89
90 cat coverage-data.txt
91
92 echo "Commits introducing uncovered code:"
93
94 commit_list=$(cat coverage-data.txt |
95         grep -E '^[0-9a-f]{7,} ' |
96         awk '{print $1;}' |
97         sort |
98         uniq)
99
100 (
101         for commit in $commit_list
102         do
103                 git log --no-decorate --pretty=format:'%an      %h: %s' -1 $commit
104                 echo
105         done
106 ) | sort
107
108 rm coverage-data.txt