Commit c9ecefea0be0673f8b3efbc37b15831d1f02a39f
Committed by
Linus Torvalds
1 parent
1d3fa37034
Exists in
master
and in
16 other branches
get_maintainer: add commit author information to --rolestats
get_maintainer currently uses "Signed-off-by" style lines to find interested parties to send patches to when the MAINTAINERS file does not have a specific section entry with a matching file pattern. Add statistics for commit authors and lines added and deleted to the information provided by --rolestats. These statistics are also emitted whenever --rolestats and --git are selected even when there is a specified maintainer. This can have the effect of expanding the number of people that are shown as possible "maintainers" of a particular file because "authors", "added_lines", and "removed_lines" are also used as criterion for the --max-maintainers option separate from the "commit_signers". The first "--git-max-maintainers" values of each criterion are emitted. Any "ties" are not shown. For example: (forcedeth does not have a named maintainer) Old output: $ ./scripts/get_maintainer.pl -f drivers/net/ethernet/nvidia/forcedeth.c "David S. Miller" <davem@davemloft.net> (commit_signer:8/10=80%) Jiri Pirko <jiri@resnulli.us> (commit_signer:2/10=20%) Patrick McHardy <kaber@trash.net> (commit_signer:2/10=20%) Larry Finger <Larry.Finger@lwfinger.net> (commit_signer:1/10=10%) Peter Zijlstra <peterz@infradead.org> (commit_signer:1/10=10%) netdev@vger.kernel.org (open list:NETWORKING DRIVERS) linux-kernel@vger.kernel.org (open list) New output: $ ./scripts/get_maintainer.pl -f drivers/net/ethernet/nvidia/forcedeth.c "David S. Miller" <davem@davemloft.net> (commit_signer:8/10=80%) Jiri Pirko <jiri@resnulli.us> (commit_signer:2/10=20%,authored:2/10=20%,removed_lines:3/33=9%) Patrick McHardy <kaber@trash.net> (commit_signer:2/10=20%,authored:2/10=20%,added_lines:12/95=13%,removed_lines:10/33=30%) Larry Finger <Larry.Finger@lwfinger.net> (commit_signer:1/10=10%,authored:1/10=10%,added_lines:35/95=37%) Peter Zijlstra <peterz@infradead.org> (commit_signer:1/10=10%) "Peter Hüwe" <PeterHuewe@gmx.de> (authored:1/10=10%,removed_lines:15/33=45%) Joe Perches <joe@perches.com> (authored:1/10=10%) Neil Horman <nhorman@tuxdriver.com> (added_lines:40/95=42%) Bill Pemberton <wfp5p@virginia.edu> (removed_lines:3/33=9%) netdev@vger.kernel.org (open list:NETWORKING DRIVERS) linux-kernel@vger.kernel.org (open list) Signed-off-by: Joe Perches <joe@perches.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 85 additions and 6 deletions Side-by-side Diff
scripts/get_maintainer.pl
... | ... | @@ -98,6 +98,7 @@ |
98 | 98 | "available" => '(which("git") ne "") && (-d ".git")', |
99 | 99 | "find_signers_cmd" => |
100 | 100 | "git log --no-color --follow --since=\$email_git_since " . |
101 | + '--numstat --no-merges ' . | |
101 | 102 | '--format="GitCommit: %H%n' . |
102 | 103 | 'GitAuthor: %an <%ae>%n' . |
103 | 104 | 'GitDate: %aD%n' . |
... | ... | @@ -106,6 +107,7 @@ |
106 | 107 | " -- \$file", |
107 | 108 | "find_commit_signers_cmd" => |
108 | 109 | "git log --no-color " . |
110 | + '--numstat ' . | |
109 | 111 | '--format="GitCommit: %H%n' . |
110 | 112 | 'GitAuthor: %an <%ae>%n' . |
111 | 113 | 'GitDate: %aD%n' . |
... | ... | @@ -114,6 +116,7 @@ |
114 | 116 | " -1 \$commit", |
115 | 117 | "find_commit_author_cmd" => |
116 | 118 | "git log --no-color " . |
119 | + '--numstat ' . | |
117 | 120 | '--format="GitCommit: %H%n' . |
118 | 121 | 'GitAuthor: %an <%ae>%n' . |
119 | 122 | 'GitDate: %aD%n' . |
... | ... | @@ -125,6 +128,7 @@ |
125 | 128 | "blame_commit_pattern" => "^([0-9a-f]+) ", |
126 | 129 | "author_pattern" => "^GitAuthor: (.*)", |
127 | 130 | "subject_pattern" => "^GitSubject: (.*)", |
131 | + "stat_pattern" => "^(\\d+)\\t(\\d+)\\t\$file\$", | |
128 | 132 | ); |
129 | 133 | |
130 | 134 | my %VCS_cmds_hg = ( |
... | ... | @@ -152,6 +156,7 @@ |
152 | 156 | "blame_commit_pattern" => "^([ 0-9a-f]+):", |
153 | 157 | "author_pattern" => "^HgAuthor: (.*)", |
154 | 158 | "subject_pattern" => "^HgSubject: (.*)", |
159 | + "stat_pattern" => "^(\\d+)\t(\\d+)\t\$file\$", | |
155 | 160 | ); |
156 | 161 | |
157 | 162 | my $conf = which_conf(".get_maintainer.conf"); |
158 | 163 | |
159 | 164 | |
160 | 165 | |
161 | 166 | |
162 | 167 | |
163 | 168 | |
164 | 169 | |
... | ... | @@ -1269,21 +1274,31 @@ |
1269 | 1274 | } |
1270 | 1275 | |
1271 | 1276 | sub vcs_find_signers { |
1272 | - my ($cmd) = @_; | |
1277 | + my ($cmd, $file) = @_; | |
1273 | 1278 | my $commits; |
1274 | 1279 | my @lines = (); |
1275 | 1280 | my @signatures = (); |
1281 | + my @authors = (); | |
1282 | + my @stats = (); | |
1276 | 1283 | |
1277 | 1284 | @lines = &{$VCS_cmds{"execute_cmd"}}($cmd); |
1278 | 1285 | |
1279 | 1286 | my $pattern = $VCS_cmds{"commit_pattern"}; |
1287 | + my $author_pattern = $VCS_cmds{"author_pattern"}; | |
1288 | + my $stat_pattern = $VCS_cmds{"stat_pattern"}; | |
1280 | 1289 | |
1290 | + $stat_pattern =~ s/(\$\w+)/$1/eeg; #interpolate $stat_pattern | |
1291 | + | |
1281 | 1292 | $commits = grep(/$pattern/, @lines); # of commits |
1282 | 1293 | |
1294 | + @authors = grep(/$author_pattern/, @lines); | |
1283 | 1295 | @signatures = grep(/^[ \t]*${signature_pattern}.*\@.*$/, @lines); |
1296 | + @stats = grep(/$stat_pattern/, @lines); | |
1284 | 1297 | |
1285 | - return (0, @signatures) if !@signatures; | |
1298 | +# print("stats: <@stats>\n"); | |
1286 | 1299 | |
1300 | + return (0, \@signatures, \@authors, \@stats) if !@signatures; | |
1301 | + | |
1287 | 1302 | save_commits_by_author(@lines) if ($interactive); |
1288 | 1303 | save_commits_by_signer(@lines) if ($interactive); |
1289 | 1304 | |
1290 | 1305 | |
... | ... | @@ -1291,9 +1306,10 @@ |
1291 | 1306 | @signatures = grep(!/${penguin_chiefs}/i, @signatures); |
1292 | 1307 | } |
1293 | 1308 | |
1309 | + my ($author_ref, $authors_ref) = extract_formatted_signatures(@authors); | |
1294 | 1310 | my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures); |
1295 | 1311 | |
1296 | - return ($commits, @$signers_ref); | |
1312 | + return ($commits, $signers_ref, $authors_ref, \@stats); | |
1297 | 1313 | } |
1298 | 1314 | |
1299 | 1315 | sub vcs_find_author { |
1300 | 1316 | |
... | ... | @@ -1849,7 +1865,12 @@ |
1849 | 1865 | sub vcs_file_signoffs { |
1850 | 1866 | my ($file) = @_; |
1851 | 1867 | |
1868 | + my $authors_ref; | |
1869 | + my $signers_ref; | |
1870 | + my $stats_ref; | |
1871 | + my @authors = (); | |
1852 | 1872 | my @signers = (); |
1873 | + my @stats = (); | |
1853 | 1874 | my $commits; |
1854 | 1875 | |
1855 | 1876 | $vcs_used = vcs_exists(); |
1856 | 1877 | |
1857 | 1878 | |
... | ... | @@ -1858,13 +1879,59 @@ |
1858 | 1879 | my $cmd = $VCS_cmds{"find_signers_cmd"}; |
1859 | 1880 | $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd |
1860 | 1881 | |
1861 | - ($commits, @signers) = vcs_find_signers($cmd); | |
1882 | + ($commits, $signers_ref, $authors_ref, $stats_ref) = vcs_find_signers($cmd, $file); | |
1862 | 1883 | |
1884 | + @signers = @{$signers_ref} if defined $signers_ref; | |
1885 | + @authors = @{$authors_ref} if defined $authors_ref; | |
1886 | + @stats = @{$stats_ref} if defined $stats_ref; | |
1887 | + | |
1888 | +# print("commits: <$commits>\nsigners:<@signers>\nauthors: <@authors>\nstats: <@stats>\n"); | |
1889 | + | |
1863 | 1890 | foreach my $signer (@signers) { |
1864 | 1891 | $signer = deduplicate_email($signer); |
1865 | 1892 | } |
1866 | 1893 | |
1867 | 1894 | vcs_assign("commit_signer", $commits, @signers); |
1895 | + vcs_assign("authored", $commits, @authors); | |
1896 | + if ($#authors == $#stats) { | |
1897 | + my $stat_pattern = $VCS_cmds{"stat_pattern"}; | |
1898 | + $stat_pattern =~ s/(\$\w+)/$1/eeg; #interpolate $stat_pattern | |
1899 | + | |
1900 | + my $added = 0; | |
1901 | + my $deleted = 0; | |
1902 | + for (my $i = 0; $i <= $#stats; $i++) { | |
1903 | + if ($stats[$i] =~ /$stat_pattern/) { | |
1904 | + $added += $1; | |
1905 | + $deleted += $2; | |
1906 | + } | |
1907 | + } | |
1908 | + my @tmp_authors = uniq(@authors); | |
1909 | + foreach my $author (@tmp_authors) { | |
1910 | + $author = deduplicate_email($author); | |
1911 | + } | |
1912 | + @tmp_authors = uniq(@tmp_authors); | |
1913 | + my @list_added = (); | |
1914 | + my @list_deleted = (); | |
1915 | + foreach my $author (@tmp_authors) { | |
1916 | + my $auth_added = 0; | |
1917 | + my $auth_deleted = 0; | |
1918 | + for (my $i = 0; $i <= $#stats; $i++) { | |
1919 | + if ($author eq deduplicate_email($authors[$i]) && | |
1920 | + $stats[$i] =~ /$stat_pattern/) { | |
1921 | + $auth_added += $1; | |
1922 | + $auth_deleted += $2; | |
1923 | + } | |
1924 | + } | |
1925 | + for (my $i = 0; $i < $auth_added; $i++) { | |
1926 | + push(@list_added, $author); | |
1927 | + } | |
1928 | + for (my $i = 0; $i < $auth_deleted; $i++) { | |
1929 | + push(@list_deleted, $author); | |
1930 | + } | |
1931 | + } | |
1932 | + vcs_assign("added_lines", $added, @list_added); | |
1933 | + vcs_assign("removed_lines", $deleted, @list_deleted); | |
1934 | + } | |
1868 | 1935 | } |
1869 | 1936 | |
1870 | 1937 | sub vcs_file_blame { |
... | ... | @@ -1887,6 +1954,10 @@ |
1887 | 1954 | if ($email_git_blame_signatures) { |
1888 | 1955 | if (vcs_is_hg()) { |
1889 | 1956 | my $commit_count; |
1957 | + my $commit_authors_ref; | |
1958 | + my $commit_signers_ref; | |
1959 | + my $stats_ref; | |
1960 | + my @commit_authors = (); | |
1890 | 1961 | my @commit_signers = (); |
1891 | 1962 | my $commit = join(" -r ", @commits); |
1892 | 1963 | my $cmd; |
1893 | 1964 | |
1894 | 1965 | |
... | ... | @@ -1894,19 +1965,27 @@ |
1894 | 1965 | $cmd = $VCS_cmds{"find_commit_signers_cmd"}; |
1895 | 1966 | $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd |
1896 | 1967 | |
1897 | - ($commit_count, @commit_signers) = vcs_find_signers($cmd); | |
1968 | + ($commit_count, $commit_signers_ref, $commit_authors_ref, $stats_ref) = vcs_find_signers($cmd, $file); | |
1969 | + @commit_authors = @{$commit_authors_ref} if defined $commit_authors_ref; | |
1970 | + @commit_signers = @{$commit_signers_ref} if defined $commit_signers_ref; | |
1898 | 1971 | |
1899 | 1972 | push(@signers, @commit_signers); |
1900 | 1973 | } else { |
1901 | 1974 | foreach my $commit (@commits) { |
1902 | 1975 | my $commit_count; |
1976 | + my $commit_authors_ref; | |
1977 | + my $commit_signers_ref; | |
1978 | + my $stats_ref; | |
1979 | + my @commit_authors = (); | |
1903 | 1980 | my @commit_signers = (); |
1904 | 1981 | my $cmd; |
1905 | 1982 | |
1906 | 1983 | $cmd = $VCS_cmds{"find_commit_signers_cmd"}; |
1907 | 1984 | $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd |
1908 | 1985 | |
1909 | - ($commit_count, @commit_signers) = vcs_find_signers($cmd); | |
1986 | + ($commit_count, $commit_signers_ref, $commit_authors_ref, $stats_ref) = vcs_find_signers($cmd, $file); | |
1987 | + @commit_authors = @{$commit_authors_ref} if defined $commit_authors_ref; | |
1988 | + @commit_signers = @{$commit_signers_ref} if defined $commit_signers_ref; | |
1910 | 1989 | |
1911 | 1990 | push(@signers, @commit_signers); |
1912 | 1991 | } |