Commit 7fa8ff2e0c0f326cdaaa4ae7d00f5d021e43ffa2

Authored by Florian Mickler
Committed by Linus Torvalds
1 parent 6ef1c52e12

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>

Showing 1 changed file with 109 additions and 38 deletions Side-by-side Diff

scripts/get_maintainer.pl
... ... @@ -295,31 +295,76 @@
295 295 }
296 296 close($maint);
297 297  
298   -my %mailmap;
299 298  
300   -if ($email_remove_duplicates) {
301   - open(my $mailmap, '<', "${lk_path}.mailmap")
  299 +#
  300 +# Read mail address map
  301 +#
  302 +
  303 +my $mailmap = read_mailmap();
  304 +
  305 +sub read_mailmap {
  306 + my $mailmap = {
  307 + names => {},
  308 + addresses => {}
  309 + };
  310 +
  311 + if (!$email_remove_duplicates) {
  312 + return $mailmap;
  313 + }
  314 +
  315 + open(my $mailmap_file, '<', "${lk_path}.mailmap")
302 316 or warn "$P: Can't open .mailmap: $!\n";
303   - while (<$mailmap>) {
304   - my $line = $_;
305 317  
306   - next if ($line =~ m/^\s*#/);
307   - next if ($line =~ m/^\s*$/);
  318 + while (<$mailmap_file>) {
  319 + s/#.*$//; #strip comments
  320 + s/^\s+|\s+$//g; #trim
308 321  
309   - my ($name, $address) = parse_email($line);
310   - $line = format_email($name, $address, $email_usename);
  322 + next if (/^\s*$/); #skip empty lines
  323 + #entries have one of the following formats:
  324 + # name1 <mail1>
  325 + # <mail1> <mail2>
  326 + # name1 <mail1> <mail2>
  327 + # name1 <mail1> name2 <mail2>
  328 + # (see man git-shortlog)
  329 + if (/^(.+)<(.+)>$/) {
  330 + my $real_name = $1;
  331 + my $address = $2;
311 332  
312   - next if ($line =~ m/^\s*$/);
  333 + $real_name =~ s/\s+$//;
  334 + $mailmap->{names}->{$address} = $real_name;
313 335  
314   - if (exists($mailmap{$name})) {
315   - my $obj = $mailmap{$name};
316   - push(@$obj, $address);
317   - } else {
318   - my @arr = ($address);
319   - $mailmap{$name} = \@arr;
  336 + } elsif (/^<([^\s]+)>\s*<([^\s]+)>$/) {
  337 + my $real_address = $1;
  338 + my $wrong_address = $2;
  339 +
  340 + $mailmap->{addresses}->{$wrong_address} = $real_address;
  341 +
  342 + } elsif (/^(.+)<([^\s]+)>\s*<([^\s]+)>$/) {
  343 + my $real_name= $1;
  344 + my $real_address = $2;
  345 + my $wrong_address = $3;
  346 +
  347 + $real_name =~ s/\s+$//;
  348 +
  349 + $mailmap->{names}->{$wrong_address} = $real_name;
  350 + $mailmap->{addresses}->{$wrong_address} = $real_address;
  351 +
  352 + } elsif (/^(.+)<([^\s]+)>\s*([^\s].*)<([^\s]+)>$/) {
  353 + my $real_name = $1;
  354 + my $real_address = $2;
  355 + my $wrong_name = $3;
  356 + my $wrong_address = $4;
  357 +
  358 + $real_name =~ s/\s+$//;
  359 + $wrong_name =~ s/\s+$//;
  360 +
  361 + $mailmap->{names}->{format_email($wrong_name,$wrong_address,1)} = $real_name;
  362 + $mailmap->{addresses}->{format_email($wrong_name,$wrong_address,1)} = $real_address;
320 363 }
321 364 }
322   - close($mailmap);
  365 + close($mailmap_file);
  366 +
  367 + return $mailmap;
323 368 }
324 369  
325 370 ## use the filenames on the command line or find the filenames in the patchfiles
326 371  
327 372  
328 373  
329 374  
330 375  
331 376  
... ... @@ -1061,32 +1106,60 @@
1061 1106 return "";
1062 1107 }
1063 1108  
1064   -sub mailmap {
1065   - my (@lines) = @_;
1066   - my %hash;
  1109 +sub mailmap_email {
  1110 + my $line = shift;
1067 1111  
1068   - foreach my $line (@lines) {
1069 1112 my ($name, $address) = parse_email($line);
1070   - if (!exists($hash{$name})) {
1071   - $hash{$name} = $address;
1072   - } elsif ($address ne $hash{$name}) {
1073   - $address = $hash{$name};
1074   - $line = format_email($name, $address, $email_usename);
1075   - }
1076   - if (exists($mailmap{$name})) {
1077   - my $obj = $mailmap{$name};
1078   - foreach my $map_address (@$obj) {
1079   - if (($map_address eq $address) &&
1080   - ($map_address ne $hash{$name})) {
1081   - $line = format_email($name, $hash{$name}, $email_usename);
  1113 + my $email = format_email($name, $address, 1);
  1114 + my $real_name = $name;
  1115 + my $real_address = $address;
  1116 +
  1117 + if (exists $mailmap->{names}->{$email} || exists $mailmap->{addresses}->{$email}) {
  1118 + if (exists $mailmap->{names}->{$email}) {
  1119 + $real_name = $mailmap->{names}->{$email};
1082 1120 }
1083   - }
  1121 + if (exists $mailmap->{addresses}->{$email}) {
  1122 + $real_address = $mailmap->{addresses}->{$email};
  1123 + }
  1124 + } else {
  1125 + if (exists $mailmap->{names}->{$address}) {
  1126 + $real_name = $mailmap->{names}->{$address};
  1127 + }
  1128 + if (exists $mailmap->{addresses}->{$address}) {
  1129 + $real_address = $mailmap->{addresses}->{$address};
  1130 + }
1084 1131 }
  1132 + return format_email($real_name, $real_address, 1);
  1133 +}
  1134 +
  1135 +sub mailmap {
  1136 + my (@addresses) = @_;
  1137 +
  1138 + my @ret = ();
  1139 + foreach my $line (@addresses) {
  1140 + push(@ret, mailmap_email($line), 1);
1085 1141 }
1086 1142  
1087   - return @lines;
  1143 + merge_by_realname(@ret) if $email_remove_duplicates;
  1144 +
  1145 + return @ret;
1088 1146 }
1089 1147  
  1148 +sub merge_by_realname {
  1149 + my %address_map;
  1150 + my (@emails) = @_;
  1151 + foreach my $email (@emails) {
  1152 + my ($name, $address) = parse_email($email);
  1153 + if (!exists $address_map{$name}) {
  1154 + $address_map{$name} = $address;
  1155 + } else {
  1156 + $address = $address_map{$name};
  1157 + $email = format_email($name,$address,1);
  1158 + }
  1159 + }
  1160 +
  1161 +}
  1162 +
1090 1163 sub git_execute_cmd {
1091 1164 my ($cmd) = @_;
1092 1165 my @lines = ();
... ... @@ -1636,9 +1709,7 @@
1636 1709 $divisor = 1;
1637 1710 }
1638 1711  
1639   - if ($email_remove_duplicates) {
1640   - @lines = mailmap(@lines);
1641   - }
  1712 + @lines = mailmap(@lines);
1642 1713  
1643 1714 return if (@lines <= 0);
1644 1715