Commit 6ef1c52e authored by Joe Perches's avatar Joe Perches Committed by Linus Torvalds

scripts/get_maintainer.pl: use case insensitive name de-duplication

Case insensitive name and email address matching can help reduce
duplication when authors don't always use the exact same signature.

o Add a --interactive per-file exact_match hash so git history
  can be checked on per-file only when there is no direct maintainer
o Make @interactive_to list global so save_commits_by_<foo> can check
  email names & addresses against this list for duplication
o Don't allow --interactive and --sections
o rename subroutine get_maintainer to get_maintainers
o Added help text option to --interactive menu prompt

Update version to 0.26-beta4
Signed-off-by: default avatarJoe Perches <joe@perches.com>
Cc: Florian Mickler <florian@mickler.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 683c6f8f
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
use strict; use strict;
my $P = $0; my $P = $0;
my $V = '0.26-beta3'; my $V = '0.26-beta4';
use Getopt::Long qw(:config no_auto_abbrev); use Getopt::Long qw(:config no_auto_abbrev);
...@@ -242,6 +242,7 @@ if ($sections) { ...@@ -242,6 +242,7 @@ if ($sections) {
$subsystem = 0; $subsystem = 0;
$web = 0; $web = 0;
$keywords = 0; $keywords = 0;
$interactive = 0;
} else { } else {
my $selections = $email + $scm + $status + $subsystem + $web; my $selections = $email + $scm + $status + $subsystem + $web;
if ($selections == 0) { if ($selections == 0) {
...@@ -407,13 +408,15 @@ my @scm = (); ...@@ -407,13 +408,15 @@ my @scm = ();
my @web = (); my @web = ();
my @subsystem = (); my @subsystem = ();
my @status = (); my @status = ();
my @interactive_to = ();
my $signature_pattern; my $signature_pattern;
my @to = get_maintainer(); my @maintainers = get_maintainers();
@to = merge_email(@to); if (@maintainers) {
@maintainers = merge_email(@maintainers);
output(@to) if (@to); output(@maintainers);
}
if ($scm) { if ($scm) {
@scm = uniq(@scm); @scm = uniq(@scm);
...@@ -437,7 +440,7 @@ if ($web) { ...@@ -437,7 +440,7 @@ if ($web) {
exit($exit); exit($exit);
sub get_maintainer { sub get_maintainers {
%email_hash_name = (); %email_hash_name = ();
%email_hash_address = (); %email_hash_address = ();
%commit_author_hash = (); %commit_author_hash = ();
...@@ -449,7 +452,7 @@ sub get_maintainer { ...@@ -449,7 +452,7 @@ sub get_maintainer {
@web = (); @web = ();
@subsystem = (); @subsystem = ();
@status = (); @status = ();
@interactive_to = ();
if ($email_git_all_signature_types) { if ($email_git_all_signature_types) {
$signature_pattern = "(.+?)[Bb][Yy]:"; $signature_pattern = "(.+?)[Bb][Yy]:";
} else { } else {
...@@ -458,10 +461,11 @@ sub get_maintainer { ...@@ -458,10 +461,11 @@ sub get_maintainer {
# Find responsible parties # Find responsible parties
my %exact_pattern_match_hash;
foreach my $file (@files) { foreach my $file (@files) {
my %hash; my %hash;
my $exact_pattern_match = 0;
my $tvi = find_first_section(); my $tvi = find_first_section();
while ($tvi < @typevalue) { while ($tvi < @typevalue) {
my $start = find_starting_index($tvi); my $start = find_starting_index($tvi);
...@@ -497,7 +501,9 @@ sub get_maintainer { ...@@ -497,7 +501,9 @@ sub get_maintainer {
my $file_pd = ($file =~ tr@/@@); my $file_pd = ($file =~ tr@/@@);
$value_pd++ if (substr($value,-1,1) ne "/"); $value_pd++ if (substr($value,-1,1) ne "/");
$value_pd = -1 if ($value =~ /^\.\*/); $value_pd = -1 if ($value =~ /^\.\*/);
$exact_pattern_match = 1 if ($value_pd >= $file_pd); if ($value_pd >= $file_pd) {
$exact_pattern_match_hash{$file} = 1;
}
if ($pattern_depth == 0 || if ($pattern_depth == 0 ||
(($file_pd - $value_pd) < $pattern_depth)) { (($file_pd - $value_pd) < $pattern_depth)) {
$hash{$tvi} = $value_pd; $hash{$tvi} = $value_pd;
...@@ -530,14 +536,6 @@ sub get_maintainer { ...@@ -530,14 +536,6 @@ sub get_maintainer {
print("\n"); print("\n");
} }
} }
if ($email && ($email_git ||
($email_git_fallback && !$exact_pattern_match))) {
vcs_file_signoffs($file);
}
if ($email && $email_git_blame) {
vcs_file_blame($file);
}
} }
if ($keywords) { if ($keywords) {
...@@ -547,6 +545,19 @@ sub get_maintainer { ...@@ -547,6 +545,19 @@ sub get_maintainer {
} }
} }
@interactive_to = (@email_to, @list_to);
foreach my $file (@files) {
if ($email &&
($email_git || ($email_git_fallback &&
!$exact_pattern_match_hash{$file}))) {
vcs_file_signoffs($file);
}
if ($email && $email_git_blame) {
vcs_file_blame($file);
}
}
if ($email) { if ($email) {
foreach my $chief (@penguin_chief) { foreach my $chief (@penguin_chief) {
if ($chief =~ m/^(.*):(.*)/) { if ($chief =~ m/^(.*):(.*)/) {
...@@ -580,7 +591,10 @@ sub get_maintainer { ...@@ -580,7 +591,10 @@ sub get_maintainer {
} }
} }
@to = interactive_get_maintainer(\@to) if ($interactive); if ($interactive) {
@interactive_to = @to;
@to = interactive_get_maintainers(\@interactive_to);
}
return @to; return @to;
} }
...@@ -899,16 +913,16 @@ sub add_categories { ...@@ -899,16 +913,16 @@ sub add_categories {
} }
if ($list_additional =~ m/subscribers-only/) { if ($list_additional =~ m/subscribers-only/) {
if ($email_subscriber_list) { if ($email_subscriber_list) {
if (!$hash_list_to{$list_address}) { if (!$hash_list_to{lc($list_address)}) {
$hash_list_to{$list_address} = 1; $hash_list_to{lc($list_address)} = 1;
push(@list_to, [$list_address, push(@list_to, [$list_address,
"subscriber list${list_role}"]); "subscriber list${list_role}"]);
} }
} }
} else { } else {
if ($email_list) { if ($email_list) {
if (!$hash_list_to{$list_address}) { if (!$hash_list_to{lc($list_address)}) {
$hash_list_to{$list_address} = 1; $hash_list_to{lc($list_address)} = 1;
push(@list_to, [$list_address, push(@list_to, [$list_address,
"open list${list_role}"]); "open list${list_role}"]);
} }
...@@ -946,8 +960,8 @@ sub email_inuse { ...@@ -946,8 +960,8 @@ sub email_inuse {
my ($name, $address) = @_; my ($name, $address) = @_;
return 1 if (($name eq "") && ($address eq "")); return 1 if (($name eq "") && ($address eq ""));
return 1 if (($name ne "") && exists($email_hash_name{$name})); return 1 if (($name ne "") && exists($email_hash_name{lc($name)}));
return 1 if (($address ne "") && exists($email_hash_address{$address})); return 1 if (($address ne "") && exists($email_hash_address{lc($address)}));
return 0; return 0;
} }
...@@ -965,8 +979,8 @@ sub push_email_address { ...@@ -965,8 +979,8 @@ sub push_email_address {
push(@email_to, [format_email($name, $address, $email_usename), $role]); push(@email_to, [format_email($name, $address, $email_usename), $role]);
} elsif (!email_inuse($name, $address)) { } elsif (!email_inuse($name, $address)) {
push(@email_to, [format_email($name, $address, $email_usename), $role]); push(@email_to, [format_email($name, $address, $email_usename), $role]);
$email_hash_name{$name}++; $email_hash_name{lc($name)}++;
$email_hash_address{$address}++; $email_hash_address{lc($address)}++;
} }
return 1; return 1;
...@@ -1259,7 +1273,7 @@ sub vcs_is_hg { ...@@ -1259,7 +1273,7 @@ sub vcs_is_hg {
return $vcs_used == 2; return $vcs_used == 2;
} }
sub interactive_get_maintainer { sub interactive_get_maintainers {
my ($list_ref) = @_; my ($list_ref) = @_;
my @list = @$list_ref; my @list = @$list_ref;
...@@ -1269,11 +1283,12 @@ sub interactive_get_maintainer { ...@@ -1269,11 +1283,12 @@ sub interactive_get_maintainer {
my %authored; my %authored;
my %signed; my %signed;
my $count = 0; my $count = 0;
my $maintained = 0;
#select maintainers by default #select maintainers by default
foreach my $entry (@list){ foreach my $entry (@list) {
my $role = $entry->[1]; my $role = $entry->[1];
$selected{$count} = ($role =~ /^(maintainer|supporter|open list)/); $selected{$count} = ($role =~ /^(maintainer|supporter|open list)/i);
$maintained = 1 if ($role =~ /^(maintainer|supporter)/i);
$authored{$count} = 0; $authored{$count} = 0;
$signed{$count} = 0; $signed{$count} = 0;
$count++; $count++;
...@@ -1286,8 +1301,14 @@ sub interactive_get_maintainer { ...@@ -1286,8 +1301,14 @@ sub interactive_get_maintainer {
while (!$done) { while (!$done) {
$count = 0; $count = 0;
if ($redraw) { if ($redraw) {
printf STDERR "\n%1s %2s %-65sauth sign\n", printf STDERR "\n%1s %2s %-65s",
"*", "#", "email/list and role:stats"; "*", "#", "email/list and role:stats";
if ($email_git ||
($email_git_fallback && !$maintained) ||
$email_git_blame) {
print STDERR "auth sign";
}
print STDERR "\n";
foreach my $entry (@list) { foreach my $entry (@list) {
my $email = $entry->[0]; my $email = $entry->[0];
my $role = $entry->[1]; my $role = $entry->[1];
...@@ -1453,6 +1474,27 @@ sub interactive_get_maintainer { ...@@ -1453,6 +1474,27 @@ sub interactive_get_maintainer {
$pattern_depth = $val; $pattern_depth = $val;
$rerun = 1; $rerun = 1;
} }
} elsif ($sel eq "h" || $sel eq "?") {
print STDERR <<EOT
Interactive mode allows you to select the various maintainers, submitters,
commit signers and mailing lists that could be CC'd on a patch.
Any *'d entry is selected.
If you have git or hg installed, You can choose to summarize the commit
history of files in the patch. Also, each line of the current file can
be matched to its commit author and that commits signers with blame.
Various knobs exist to control the length of time for active commit
tracking, the maximum number of commit authors and signers to add,
and such.
Enter selections at the prompt until you are satisfied that the selected
maintainers are appropriate. You may enter multiple selections separated
by either commas or spaces.
EOT
} else { } else {
print STDERR "invalid option: '$nr'\n"; print STDERR "invalid option: '$nr'\n";
$redraw = 0; $redraw = 0;
...@@ -1461,7 +1503,7 @@ sub interactive_get_maintainer { ...@@ -1461,7 +1503,7 @@ sub interactive_get_maintainer {
if ($rerun) { if ($rerun) {
print STDERR "git-blame can be very slow, please have patience..." print STDERR "git-blame can be very slow, please have patience..."
if ($email_git_blame); if ($email_git_blame);
goto &get_maintainer; goto &get_maintainers;
} }
} }
...@@ -1496,9 +1538,20 @@ sub save_commits_by_author { ...@@ -1496,9 +1538,20 @@ sub save_commits_by_author {
foreach my $line (@lines) { foreach my $line (@lines) {
if ($line =~ m/$VCS_cmds{"author_pattern"}/) { if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
my $matched = 0;
my $author = $1; my $author = $1;
my ($name, $address) = parse_email($author); my ($name, $address) = parse_email($author);
$author = format_email($name, $address, 1); foreach my $to (@interactive_to) {
my ($to_name, $to_address) = parse_email($to->[0]);
if ($email_remove_duplicates &&
((lc($name) eq lc($to_name)) ||
(lc($address) eq lc($to_address)))) {
$author = $to->[0];
$matched = 1;
last;
}
}
$author = format_email($name, $address, 1) if (!$matched);
push(@authors, $author); push(@authors, $author);
} }
push(@commits, $1) if ($line =~ m/$VCS_cmds{"commit_pattern"}/); push(@commits, $1) if ($line =~ m/$VCS_cmds{"commit_pattern"}/);
...@@ -1539,6 +1592,20 @@ sub save_commits_by_signer { ...@@ -1539,6 +1592,20 @@ sub save_commits_by_signer {
my $type = $types[0]; my $type = $types[0];
my $signer = $signers[0]; my $signer = $signers[0];
my $matched = 0;
my ($name, $address) = parse_email($signer);
foreach my $to (@interactive_to) {
my ($to_name, $to_address) = parse_email($to->[0]);
if ($email_remove_duplicates &&
((lc($name) eq lc($to_name)) ||
(lc($address) eq lc($to_address)))) {
$signer = $to->[0];
$matched = 1;
last;
}
$signer = format_email($name, $address, 1) if (!$matched);
}
my $exists = 0; my $exists = 0;
foreach my $ref(@{$commit_signer_hash{$signer}}) { foreach my $ref(@{$commit_signer_hash{$signer}}) {
if (@{$ref}[0] eq $commit && if (@{$ref}[0] eq $commit &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment