contrib / coverage-diff.shon commit Git 2.21-rc1 (8989e19)
   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
  13V1=$1
  14V2=$2
  15
  16diff_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
  45files=$(git diff --name-only "$V1" "$V2" -- \*.c)
  46
  47# create empty file
  48>coverage-data.txt
  49
  50for file in $files
  51do
  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
  88done
  89
  90cat coverage-data.txt
  91
  92echo "Commits introducing uncovered code:"
  93
  94commit_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
 108rm coverage-data.txt