scripts/get_maintainer.pl: fix mailmap handling

Implement it, like it is described in git-shortlog.

Signed-off-by: Florian Mickler <florian@mickler.org>
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>
This commit is contained in:
Florian Mickler 2010-10-26 14:22:56 -07:00 committed by Linus Torvalds
parent 6ef1c52e12
commit 7fa8ff2e0c
1 changed files with 109 additions and 38 deletions

View File

@ -295,31 +295,76 @@ while (<$maint>) {
} }
close($maint); close($maint);
my %mailmap;
if ($email_remove_duplicates) { #
open(my $mailmap, '<', "${lk_path}.mailmap") # Read mail address map
#
my $mailmap = read_mailmap();
sub read_mailmap {
my $mailmap = {
names => {},
addresses => {}
};
if (!$email_remove_duplicates) {
return $mailmap;
}
open(my $mailmap_file, '<', "${lk_path}.mailmap")
or warn "$P: Can't open .mailmap: $!\n"; or warn "$P: Can't open .mailmap: $!\n";
while (<$mailmap>) {
my $line = $_;
next if ($line =~ m/^\s*#/); while (<$mailmap_file>) {
next if ($line =~ m/^\s*$/); s/#.*$//; #strip comments
s/^\s+|\s+$//g; #trim
my ($name, $address) = parse_email($line); next if (/^\s*$/); #skip empty lines
$line = format_email($name, $address, $email_usename); #entries have one of the following formats:
# name1 <mail1>
# <mail1> <mail2>
# name1 <mail1> <mail2>
# name1 <mail1> name2 <mail2>
# (see man git-shortlog)
if (/^(.+)<(.+)>$/) {
my $real_name = $1;
my $address = $2;
next if ($line =~ m/^\s*$/); $real_name =~ s/\s+$//;
$mailmap->{names}->{$address} = $real_name;
if (exists($mailmap{$name})) { } elsif (/^<([^\s]+)>\s*<([^\s]+)>$/) {
my $obj = $mailmap{$name}; my $real_address = $1;
push(@$obj, $address); my $wrong_address = $2;
} else {
my @arr = ($address); $mailmap->{addresses}->{$wrong_address} = $real_address;
$mailmap{$name} = \@arr;
} elsif (/^(.+)<([^\s]+)>\s*<([^\s]+)>$/) {
my $real_name= $1;
my $real_address = $2;
my $wrong_address = $3;
$real_name =~ s/\s+$//;
$mailmap->{names}->{$wrong_address} = $real_name;
$mailmap->{addresses}->{$wrong_address} = $real_address;
} elsif (/^(.+)<([^\s]+)>\s*([^\s].*)<([^\s]+)>$/) {
my $real_name = $1;
my $real_address = $2;
my $wrong_name = $3;
my $wrong_address = $4;
$real_name =~ s/\s+$//;
$wrong_name =~ s/\s+$//;
$mailmap->{names}->{format_email($wrong_name,$wrong_address,1)} = $real_name;
$mailmap->{addresses}->{format_email($wrong_name,$wrong_address,1)} = $real_address;
} }
} }
close($mailmap); close($mailmap_file);
return $mailmap;
} }
## use the filenames on the command line or find the filenames in the patchfiles ## use the filenames on the command line or find the filenames in the patchfiles
@ -1061,30 +1106,58 @@ sub which_conf {
return ""; return "";
} }
sub mailmap { sub mailmap_email {
my (@lines) = @_; my $line = shift;
my %hash;
foreach my $line (@lines) {
my ($name, $address) = parse_email($line); my ($name, $address) = parse_email($line);
if (!exists($hash{$name})) { my $email = format_email($name, $address, 1);
$hash{$name} = $address; my $real_name = $name;
} elsif ($address ne $hash{$name}) { my $real_address = $address;
$address = $hash{$name};
$line = format_email($name, $address, $email_usename); if (exists $mailmap->{names}->{$email} || exists $mailmap->{addresses}->{$email}) {
} if (exists $mailmap->{names}->{$email}) {
if (exists($mailmap{$name})) { $real_name = $mailmap->{names}->{$email};
my $obj = $mailmap{$name}; }
foreach my $map_address (@$obj) { if (exists $mailmap->{addresses}->{$email}) {
if (($map_address eq $address) && $real_address = $mailmap->{addresses}->{$email};
($map_address ne $hash{$name})) { }
$line = format_email($name, $hash{$name}, $email_usename); } else {
if (exists $mailmap->{names}->{$address}) {
$real_name = $mailmap->{names}->{$address};
}
if (exists $mailmap->{addresses}->{$address}) {
$real_address = $mailmap->{addresses}->{$address};
} }
}
} }
return format_email($real_name, $real_address, 1);
}
sub mailmap {
my (@addresses) = @_;
my @ret = ();
foreach my $line (@addresses) {
push(@ret, mailmap_email($line), 1);
} }
return @lines; merge_by_realname(@ret) if $email_remove_duplicates;
return @ret;
}
sub merge_by_realname {
my %address_map;
my (@emails) = @_;
foreach my $email (@emails) {
my ($name, $address) = parse_email($email);
if (!exists $address_map{$name}) {
$address_map{$name} = $address;
} else {
$address = $address_map{$name};
$email = format_email($name,$address,1);
}
}
} }
sub git_execute_cmd { sub git_execute_cmd {
@ -1636,9 +1709,7 @@ sub vcs_assign {
$divisor = 1; $divisor = 1;
} }
if ($email_remove_duplicates) { @lines = mailmap(@lines);
@lines = mailmap(@lines);
}
return if (@lines <= 0); return if (@lines <= 0);