Commit c9ecefea0be0673f8b3efbc37b15831d1f02a39f

Authored by Joe Perches
Committed by Linus Torvalds
1 parent 1d3fa37034

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 }