{"thread":{"id":"13726","subject":"whomto.pl -- finding out whom to send patches to","startedAt":"2008-05-29T18:20:33Z","lastAt":"2008-05-31T10:33:58Z","messageCount":8,"participants":["Vegard Nossum","Joe Perches","Jesper Juhl","Junio C Hamano","Andrea Righi","Roel"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"78089","messageId":"1212085233.27103.54.camel@localhost","threadId":"13726","inReplyTo":"20080529210018.GA5508@damson.getinternet.no","subject":"Re: whomto.pl -- finding out whom to send patches to","fromName":"Joe Perches","fromEmail":"joe@perches.com","sentAt":"2008-05-29T18:20:33Z","receivedAt":"2008-05-29T18:20:33Z","isPatch":false,"sender":{"key":"joe@perches.com","avatar":"https://avatars.githubusercontent.com/u/13122723?v=4"},"body":"> I've written this perl script that takes a patch as input and prints the\n> authors/committers of the affected lines, using git-blame as the back end.\n\nNice enough script.\nIt's unfortunate that it can't output the appropriate mailing lists.\n\nI think the shell script that Linus gave awhile ago:\nhttp://lkml.org/lkml/2007/8/14/276\n\n        #!/bin/sh\n               git log --since=6.months.ago -- \"$@\" |\n                       grep -i '^    [-a-z]*by:.*@' |\n                       sort | uniq -c |\n                       sort -r -n | head\n        \n         (Maybe you want to add a\n               grep -v '\\(Linus Torvalds\\)\\|\\(Andrew Morton\\)'\n        \nmight work just as well.\n\nI still prefer the file pattern match in MAINTAINERS, or\nanother external file, and/or data stored directly into GIT\nvia gitattributes approaches.\n\nThis script can give maintainer, mailing lists, and git\ncontact information for patches or files.\nhttp://lkml.org/lkml/2007/8/20/352\nThe script works with git-send-email to cc the appropriate parties.\n\nThis script and git repository is very old and probably doesn't apply...\ngit pull git://repo.or.cz/linux-2.6/trivial-mods.git get_maintainer\n"},{"id":"78086","messageId":"20080529210018.GA5508@damson.getinternet.no","threadId":"13726","inReplyTo":null,"subject":"whomto.pl -- finding out whom to send patches to","fromName":"Vegard Nossum","fromEmail":"vegard.nossum@gmail.com","sentAt":"2008-05-29T21:00:18Z","receivedAt":"2008-05-29T21:00:18Z","isPatch":false,"sender":{"key":"vegard.nossum@gmail.com","avatar":null},"body":"Hi,\n\nI've written this perl script that takes a patch as input and prints the\nauthors/committers of the affected lines, using git-blame as the back end.\n\n(The purpose of this is of course to find out whom to send patches to.)\n\nThere are some caveats:\n\n- If I've understood correctly, git-blame incremental output doesn't split\n  commits when a newer one is found, so we currently possibly take into\n  account more than just the last patch to touch a line. This might not be\n  a disadvantage, however...\n\n- The patch must apply to the current working tree. I suppose there is\n  some way to use the index information in the patch to determine what to\n  run git-blame against, but this is currently beyond my git knowledge.\n\n- It's a bit slow, particularly for large files. But doing the same thing\n  by hand would be slower, so I suppose it's an overall improvement.\n\nRunning this on a random -mm patch, for example\nhttp://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.26-rc2/2.6.26-rc2-mm1/broken-out/acpi-fix-fadt-parsing.patch\ngives the following output:\n\n  $ perl whomto2.pl acpi-fix-fadt-parsing.patch\n  Running git-blame on drivers/acpi/tables/tbfadt.c...\n\n  To: (Committers)\n      48 Len Brown <len.brown@intel.com>\n  Cc: (Authors)\n      44 Bob Moore <robert.moore@intel.com>\n       2 Alexey Starikovskiy <alexey.y.starikovskiy@linux.intel.com>\n       2 Len Brown <len.brown@intel.com>\n\nMaybe this tool can be useful? :-)\n\n(Improvements are of course also welcome.)\n\n\nVegard\n\n\n#! /usr/bin/perl\n\nuse strict;\nuse warnings;\n\nfor my $file (@ARGV) {\n\tcheck($file);\n}\n\nsub git_apply {\n\tmy $filename = shift;\n\n\tmy @args = (\n\t\t'git-apply',\n\t\t'--check',\n\t\t$filename,\n\t);\n\n\topen(my $fh, '-|', @args) || die $!;\n\tmy @b = <$fh>;\n\tclose $fh;\n\n\treturn $? ? undef : 1;\n}\n\nsub git_blame {\n\tmy $filename = shift;\n\n\tmy @args = (\n\t\t'git-blame',\n\t\t'--incremental',\n\t\t'--',\n\t\t$filename,\n\t);\n\n\topen(my $fh, '-|', @args) || die $!;\n\tchomp(my @b = <$fh>);\n\tclose $fh;\n\n\tmy %info = ();\n\n\tmy %commits = ();\n\n\tmy @blames = ();\n\tmy $blame;\n\n\tmy $start = 1;\n\tfor (@b) {\n\t\tif ($start) {\n\t\t\tmy($sha1, $source, $result, $num) = split;\n\n\t\t\t$blame = {\n\t\t\t\tsha1 => $sha1,\n\t\t\t\tsource => $source,\n\t\t\t\tresult => $result,\n\t\t\t\tnum => $num,\n\t\t\t};\n\n\t\t\t%info = ();\n\n\t\t\t$start = 0;\n\t\t\tnext;\n\t\t}\n\n\t\tmy($key, $value) = split m/ /, $_, 2;\n\t\t$info{$key} = $value;\n\n\t\tif ($key eq 'filename') {\n\t\t\tmy $sha1 = $blame->{sha1};\n\t\t\t$commits{$sha1} = {%info} unless exists $commits{$sha1};\n\n\t\t\tpush @blames, $blame;\n\t\t\t$start = 1\n\t\t}\n\t}\n\n\treturn $? ? undef : {\n\t\tcommits => \\%commits,\n\t\tblames => \\@blames,\n\t};\n}\n\nsub parse_patch {\n\tmy $filename = shift;\n\n\topen(my $fh, '<', $filename);\n\tchomp(my @p = <$fh>);\n\tclose($fh);\n\n\tmy %headers = ();\n\tfor my $line (@p) {\n\t\tlast if $line eq '';\n\n\t\tif(my($key, $value) = split m/: /, $line, 2) {\n\t\t\t$headers{$key} = $value;\n\t\t}\n\t}\n\n\tmy %files = ();\n\tmy $file;\n\n\tfor (@p) {\n\t\tif (m/^--- .*?\\/([^\\s~]*)/) {\n\t\t\t$file = $files{$1} = {\n\t\t\t\tchunks => [],\n\t\t\t};\n\t\t\tnext;\n\t\t}\n\n\t\tif (m/^@@ -(\\d+),(\\d+) \\+\\d+,\\d+ @@/) {\n\t\t\tpush @{$file->{chunks}}, [$1, $2];\n\t\t\tnext;\n\t\t}\n\t}\n\n\treturn {\n\t\theaders => \\%headers,\n\t\tfiles => \\%files,\n\t};\n}\n\nsub min {\n\treturn $_[0] if $_[0] < $_[1];\n\treturn $_[1];\n}\n\nsub max {\n\treturn $_[0] if $_[0] > $_[1];\n\treturn $_[1];\n}\n\nsub range_intersect {\n\treturn [max($_[0], $_[2]), min($_[1], $_[3])];\n}\n\nsub range_size {\n\treturn 0 if $_[0]->[0] > $_[0]->[1];\n\treturn $_[0]->[1] - $_[0]->[0] + 1;\n}\n\nsub check_chunk {\n\tmy $blame = shift;\n\tmy $chunk = shift;\n\n\tmy @results = ();\n\n\tmy $a = $chunk->[0];\n\tmy $b = $chunk->[0] + $chunk->[1] - 1;\n\n\tmy $blames = $blame->{blames};\n\tfor my $blame_chunk (@$blames) {\n\t\tmy $c = $blame_chunk->{source};\n\t\tmy $d = $blame_chunk->{source} + $blame_chunk->{num} - 1;\n\n\t\tmy $size = range_size(range_intersect($a, $b, $c, $d));\n\t\tif ($size > 0) {\n\t\t\tpush @results, {\n\t\t\t\tsha1 => $blame_chunk->{sha1},\n\t\t\t\tsize => $size,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn \\@results;\n}\n\nsub best_email {\n\tmy $emails = shift;\n\n\tmy $best = (keys %$emails)[0];\n\tfor my $email (keys %$emails) {\n\t\t$best = $email if $emails->{$email} < $emails->{$best};\n\t}\n\n\treturn $best;\n}\n\nsub hash_sort {\n\tmy $h = shift;\n\n\treturn sort { $h->{$a} <=> $h->{$b} } keys %$h;\n}\n\nsub check {\n\tmy $filename = shift;\n\n\t# First try to apply the patch. This makes sure the patched files\n\t# exist in the first place, and that the line numbers are semi-\n\t# correct.\n\tgit_apply($filename) || die \"Patch won't apply.\\n\";\n\n\t# Get files and line numbers from the patch.\n\tmy $patch = parse_patch($filename);\n\n\tmy %all_commits = ();\n\tmy @all_results = ();\n\n\tmy $files = $patch->{'files'};\n\tfor my $file (keys %$files) {\n\t\tprintf STDERR \"Running git-blame on %s...\\n\", $file;\n\n\t\tmy $blame = git_blame($file) || die \"git-blame failed\\n\";\n\n\t\t%all_commits = (%all_commits, %{$blame->{commits}});\n\n\t\tmy $chunks = $files->{$file}->{chunks};\n\t\tfor my $chunk (@$chunks) {\n\t\t\tpush @all_results, @{check_chunk($blame, $chunk)};\n\t\t}\n\t}\n\n\tprint STDERR \"\\n\";\n\n\t# Flatten the commit data to store person -> email information\n\tmy %emails = ();\n\tfor my $commit (values %all_commits) {\n\t\tmy $author = $commit->{author};\n\t\tmy $author_mail = $commit->{'author-mail'};\n\t\t$emails{$author} = {} unless exists $emails{$author};\n\t\t$emails{$author}->{$author_mail} = 0 unless exists $emails{$author}->{$author_mail};\n\t\t$emails{$author}->{$author_mail}++;\n\n\t\tmy $committer = $commit->{committer};\n\t\tmy $committer_mail = $commit->{'committer-mail'};\n\t\t$emails{$committer} = {} unless exists $emails{$committer};\n\t\t$emails{$committer}->{$committer_mail} = 0 unless exists $emails{$committer}->{$committer_mail};\n\t\t$emails{$committer}->{$committer_mail}++;\n\t}\n\n\t# Find authors and committers...\n\tmy %authors = ();\n\tmy %committers = ();\n\tfor my $result (@all_results) {\n\t\tmy $commit = $all_commits{$result->{sha1}};\n\t\tmy $author = $commit->{author};\n\t\tmy $committer = $commit->{committer};\n\n\t\t$authors{$author} = 0 unless exists $authors{$author};\n\t\t$authors{$author} += $result->{size};\n\n\t\t$committers{$committer} = 0 unless exists $committers{$committer};\n\t\t$committers{$committer} += $result->{size};\n\t}\n\n\tprint \"To: (Committers)\\n\";\n\tfor my $committer (reverse hash_sort \\%committers) {\n\t\tprintf \"%6d %s %s\\n\",\n\t\t\t$committers{$committer},\n\t\t\t$committer,\n\t\t\tbest_email($emails{$committer});\n\t}\n\n\tprint \"Cc: (Authors)\\n\";\n\tfor my $author (reverse hash_sort \\%authors) {\n\t\tprintf \"%6d %s %s\\n\",\n\t\t\t$authors{$author},\n\t\t\t$author,\n\t\t\tbest_email($emails{$author});\n\t}\n}\n"},{"id":"78091","messageId":"9a8748490805291519l18a88d1bj6d5ffa2b88c19b1d@mail.gmail.com","threadId":"13726","inReplyTo":"20080529210018.GA5508@damson.getinternet.no","subject":"Re: whomto.pl -- finding out whom to send patches to","fromName":"Jesper Juhl","fromEmail":"jesper.juhl@gmail.com","sentAt":"2008-05-29T22:19:23Z","receivedAt":"2008-05-29T22:19:23Z","isPatch":false,"sender":{"key":"jesper.juhl@gmail.com","avatar":null},"body":"2008/5/29 Vegard Nossum <vegard.nossum@gmail.com>:\n> Hi,\n>\n> I've written this perl script that takes a patch as input and prints the\n> authors/committers of the affected lines, using git-blame as the back end.\n>\n> (The purpose of this is of course to find out whom to send patches to.)\n>\n<snip>\n\nThe script is nice, but I'd wish it looked at a few other things as well.\n\nWhen I personally need to determine who to send patches to I do use\n'git blame' for some of the addresses, but in addition to that I also\ncheck;\n\n- The comments at the top of the file.  Sometimes there are email\naddresses there for relevant people (sometimes just names, but\naddresses can then usually be found for those people in CREDITS or\nMAINTAINERS).\n\n- Entries in MAINTAINERS that are relevant to the subsystem and/or\nfile I'm modifying.\n\n- Entries in CREDITS that look relevant to the subsystem and/or file\nI'm modifying.\n\n- Names/email addresses in files in Documentation/ that are relevant\nto the subsystem/file I'm modifying.\n\nIf the script could be made to check all (or just some) of those\nsources as well it would be really great.\n\n-- \nJesper Juhl <jesper.juhl@gmail.com>\nDon't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html\nPlain text mails only, please http://www.expita.com/nomime.html\n"},{"id":"78096","messageId":"7vr6bkofct.fsf@gitster.siamese.dyndns.org","threadId":"13726","inReplyTo":"20080529210018.GA5508@damson.getinternet.no","subject":"Re: whomto.pl -- finding out whom to send patches to","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-29T23:33:22Z","receivedAt":"2008-05-29T23:33:22Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Vegard Nossum <vegard.nossum@gmail.com> writes:\n\n> I've written this perl script that takes a patch as input and prints the\n> authors/committers of the affected lines, using git-blame as the back end.\n>\n> (The purpose of this is of course to find out whom to send patches to.)\n>\n> There are some caveats:\n>\n> - If I've understood correctly, git-blame incremental output doesn't split\n>   commits when a newer one is found, so we currently possibly take into\n>   account more than just the last patch to touch a line. This might not be\n>   a disadvantage, however...\n\n\"git blame\" does not give irrelevant commits in its output, with or\nwithout --incremental.  Perhaps you were thinking about the \"oops, earlier\none was wrong, here are the corrections\" behaviour of \"git log\n--early-output\", which is an unrelated mechanism in a different command.\n\nBut I have to wonder why you used --incremental and not --porcelain\nformat, the latter of which is more compact and is designed for parsing by\ntools.\n\nI also have to wonder why you did not use -M, -C, and/or -w, if you used\nblame to find the true origin of lines that are involved.\n\nUnless the patch is truly about a narrow region of a handful files\n(e.g. micro-optimizing the implementation of a single function without\nchanging its external interface at all, or fixing an off-by-one error in a\ngroup of functions that do similar things), I suspect that it would make\nmore sense to use \"git shortlog --no-merges -- paths\" to get the list of\npeople who are involved in the general area, even though they may not have\nbeen involved in particular _lines_ that the patch touches.  For example,\nif a patch changes the lines in a function's implementation, you would\nwant input not only from the people who improved the implementation of the\nfunction over the years, but more from the people who care about the\ncalling sites of that function the patch is touching.\n"},{"id":"78117","messageId":"483FB39A.4070104@gmail.com","threadId":"13726","inReplyTo":"20080529210018.GA5508@damson.getinternet.no","subject":"Re: whomto.pl -- finding out whom to send patches to","fromName":"Andrea Righi","fromEmail":"righi.andrea@gmail.com","sentAt":"2008-05-30T07:58:19Z","receivedAt":"2008-05-30T07:58:19Z","isPatch":false,"sender":{"key":"righi.andrea@gmail.com","avatar":null},"body":"Vegard Nossum wrote:\n> Hi,\n> \n> I've written this perl script that takes a patch as input and prints the\n> authors/committers of the affected lines, using git-blame as the back end.\n> \n> (The purpose of this is of course to find out whom to send patches to.)\n> \n> There are some caveats:\n> \n> - If I've understood correctly, git-blame incremental output doesn't split\n>   commits when a newer one is found, so we currently possibly take into\n>   account more than just the last patch to touch a line. This might not be\n>   a disadvantage, however...\n> \n> - The patch must apply to the current working tree. I suppose there is\n>   some way to use the index information in the patch to determine what to\n>   run git-blame against, but this is currently beyond my git knowledge.\n> \n> - It's a bit slow, particularly for large files. But doing the same thing\n>   by hand would be slower, so I suppose it's an overall improvement.\n> \n> Running this on a random -mm patch, for example\n> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.26-rc2/2.6.26-rc2-mm1/broken-out/acpi-fix-fadt-parsing.patch\n> gives the following output:\n> \n>   $ perl whomto2.pl acpi-fix-fadt-parsing.patch\n>   Running git-blame on drivers/acpi/tables/tbfadt.c...\n> \n>   To: (Committers)\n>       48 Len Brown <len.brown@intel.com>\n>   Cc: (Authors)\n>       44 Bob Moore <robert.moore@intel.com>\n>        2 Alexey Starikovskiy <alexey.y.starikovskiy@linux.intel.com>\n>        2 Len Brown <len.brown@intel.com>\n> \n> Maybe this tool can be useful? :-)\n> \n> (Improvements are of course also welcome.)\n\nMinor fix: do not git-blame /dev/null in patches that add new files.\n\n-Andrea\n\ndiff -urpN linux/whomto.orig.pl linux/whomto.pl\n--- linux/whomto.orig.pl\t2008-05-30 09:43:08.000000000 +0200\n+++ linux/whomto.pl\t2008-05-30 09:49:26.000000000 +0200\n@@ -101,6 +101,7 @@ sub parse_patch {\n \n \tfor (@p) {\n \t\tif (m/^--- .*?\\/([^\\s~]*)/) {\n+\t\t\tnext if ($1 eq 'dev/null');\n \t\t\t$file = $files{$1} = {\n \t\t\t\tchunks => [],\n \t\t\t};\n"},{"id":"78121","messageId":"483FC90E.3020404@gmail.com","threadId":"13726","inReplyTo":"20080529210018.GA5508@damson.getinternet.no","subject":"Re: whomto.pl -- finding out whom to send patches to","fromName":"Roel","fromEmail":"roel.kluin@gmail.com","sentAt":"2008-05-30T09:29:50Z","receivedAt":"2008-05-30T09:29:50Z","isPatch":false,"sender":{"key":"roel.kluin@gmail.com","avatar":null},"body":"Vegard Nossum schreef:\n> Hi,\n>\n> I've written this perl script that takes a patch as input and prints the\n> authors/committers of the affected lines, using git-blame as the back end.\n>\n> (The purpose of this is of course to find out whom to send patches to.)\n>\n> There are some caveats:\n>\n> - If I've understood correctly, git-blame incremental output doesn't split\n>   commits when a newer one is found, so we currently possibly take into\n>   account more than just the last patch to touch a line. This might not be\n>   a disadvantage, however...\n>\n> - The patch must apply to the current working tree. I suppose there is\n>   some way to use the index information in the patch to determine what to\n>   run git-blame against, but this is currently beyond my git knowledge.\n>\n> - It's a bit slow, particularly for large files. But doing the same thing\n>   by hand would be slower, so I suppose it's an overall improvement.\n>\n> Running this on a random -mm patch, for example\n> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.26-rc2/2.6.26-rc2-mm1/broken-out/acpi-fix-fadt-parsing.patch\n> gives the following output:\n>\n>   $ perl whomto2.pl acpi-fix-fadt-parsing.patch\n>   Running git-blame on drivers/acpi/tables/tbfadt.c...\n>\n>   To: (Committers)\n>       48 Len Brown <len.brown@intel.com>\n>   Cc: (Authors)\n>       44 Bob Moore <robert.moore@intel.com>\n>        2 Alexey Starikovskiy <alexey.y.starikovskiy@linux.intel.com>\n>        2 Len Brown <len.brown@intel.com>\n>\n> Maybe this tool can be useful? :-)\n>\n> (Improvements are of course also welcome.)\n>\n>\n> Vegard\n\nBased on Linus' script to get the email address of a maintainer, I wrote \nthis bash script to get\nan indication of relevant lists. Maybe you can make use of the part that \nparses the\nMAINTAINERS file for relevant lists?\n\n---\n\ngit log --since=\"1 year ago\"  \"$@\" | sed -n \"s/^    .[-a-z]*by: \\(.*\\) <.*$/\\1/p\" |\nsort | uniq | sort -n -r | while read -r name; do\n        sed -n \"/^P:[ \\t]*.*$name/,/^$/{\n                s/^L:[ \\t]*\\(.*\\)$/\\1/p\n        }\" ./MAINTAINERS\ndone | sort | uniq -c | sort -n -r | while read -r nr list; do\n        tot=`grep -c \"^L:\\W*.*$list.*\" ./MAINTAINERS`\n        echo \"`expr $nr / \\( $tot + 1 \\)` $nr $tot $list\"\ndone | sort -r | cut -d \" \" -f2- | while read -r nr tot list; do\n        echo -e \"$nr/$tot Acks were commited by maintainers of list $list\"\ndone\n"},{"id":"78210","messageId":"19f34abd0805310303i526f6b4dv167355103665ac42@mail.gmail.com","threadId":"13726","inReplyTo":"483FB39A.4070104@gmail.com","subject":"Re: whomto.pl -- finding out whom to send patches to","fromName":"Vegard Nossum","fromEmail":"vegard.nossum@gmail.com","sentAt":"2008-05-31T10:03:54Z","receivedAt":"2008-05-31T10:03:54Z","isPatch":false,"sender":{"key":"vegard.nossum@gmail.com","avatar":null},"body":"On 5/30/08, Andrea Righi <righi.andrea@gmail.com> wrote:\n> Vegard Nossum wrote:\n>\n> > Hi,\n> >\n> > I've written this perl script that takes a patch as input and prints the\n> > authors/committers of the affected lines, using git-blame as the back end.\n\n...\n\n> > (Improvements are of course also welcome.)\n> >\n>\n>  Minor fix: do not git-blame /dev/null in patches that add new files.\n>\n>  -Andrea\n>\n>  diff -urpN linux/whomto.orig.pl linux/whomto.pl\n>  --- linux/whomto.orig.pl        2008-05-30 09:43:08.000000000 +0200\n>  +++ linux/whomto.pl     2008-05-30 09:49:26.000000000 +0200\n>  @@ -101,6 +101,7 @@ sub parse_patch {\n>\n>         for (@p) {\n>                 if (m/^--- .*?\\/([^\\s~]*)/) {\n>  +                       next if ($1 eq 'dev/null');\n>                         $file = $files{$1} = {\n>                                 chunks => [],\n>                         };\n>\n\nI missed that, thanks :-)\n\n(Other diff programs may also use other paths for new files, so I'm\nalso adding an -f check.)\n\n\nVegard\n\n-- \n\"The animistic metaphor of the bug that maliciously sneaked in while\nthe programmer was not looking is intellectually dishonest as it\ndisguises that the error is the programmer's own creation.\"\n\t-- E. W. Dijkstra, EWD1036\n"},{"id":"78215","messageId":"19f34abd0805310333s270ab8e5pec3396a4539fd797@mail.gmail.com","threadId":"13726","inReplyTo":"7vr6bkofct.fsf@gitster.siamese.dyndns.org","subject":"Re: whomto.pl -- finding out whom to send patches to","fromName":"Vegard Nossum","fromEmail":"vegard.nossum@gmail.com","sentAt":"2008-05-31T10:33:58Z","receivedAt":"2008-05-31T10:33:58Z","isPatch":false,"sender":{"key":"vegard.nossum@gmail.com","avatar":null},"body":"Hi,\n\nOn 5/30/08, Junio C Hamano <gitster@pobox.com> wrote:\n> Vegard Nossum <vegard.nossum@gmail.com> writes:\n>\n>  > I've written this perl script that takes a patch as input and prints the\n>  > authors/committers of the affected lines, using git-blame as the back end.\n>  >\n>  > (The purpose of this is of course to find out whom to send patches to.)\n>  >\n>  > There are some caveats:\n>  >\n>  > - If I've understood correctly, git-blame incremental output doesn't split\n>  >   commits when a newer one is found, so we currently possibly take into\n>  >   account more than just the last patch to touch a line. This might not be\n>  >   a disadvantage, however...\n>\n>\n> \"git blame\" does not give irrelevant commits in its output, with or\n>  without --incremental.  Perhaps you were thinking about the \"oops, earlier\n>  one was wrong, here are the corrections\" behaviour of \"git log\n>  --early-output\", which is an unrelated mechanism in a different command.\n>\n\nThis comment was based on my observation that several (sometimes\ndifferent) commits would span the same line numbers. Though it seems\nto also happen that no line is spanned by any commit at all. I\nprobably misunderstood the output format of the incremental mode.\n\n>  But I have to wonder why you used --incremental and not --porcelain\n>  format, the latter of which is more compact and is designed for parsing by\n>  tools.\n>\n\nThere were some different reasons. I found --incremental easier to\nparse, and I didn't really want the actual lines of the file. Maybe I\nshould rewrite to use porcelain instead :-)\n\n>  I also have to wonder why you did not use -M, -C, and/or -w, if you used\n>  blame to find the true origin of lines that are involved.\n>\n\nI haven't used these options before and didn't know if it would really\nmake sense to use them in this context. I guess I could allow them to\npass through from the command line to git-blame...\n\n>  Unless the patch is truly about a narrow region of a handful files\n>  (e.g. micro-optimizing the implementation of a single function without\n>  changing its external interface at all, or fixing an off-by-one error in a\n>  group of functions that do similar things), I suspect that it would make\n>  more sense to use \"git shortlog --no-merges -- paths\" to get the list of\n>  people who are involved in the general area, even though they may not have\n>  been involved in particular _lines_ that the patch touches.  For example,\n>  if a patch changes the lines in a function's implementation, you would\n>  want input not only from the people who improved the implementation of the\n>  function over the years, but more from the people who care about the\n>  calling sites of that function the patch is touching.\n\nYes, it seems that log/shortlog is the most common (and probably\nfaster) way of doing what I'm trying to do, based on all the feedback\nI had :-) However, I use git-blame myself and so I wanted to automate\nthat task in particular.\n\nI did not intend for the tool to be fully automatic, however; it\noutputs a ranked list of names and e-mails. The user (well, me ;-)) is\nstill expected to pick the sensible entries and leave out the rest.\nFor instance, I bet half the patches run through the script on the\nlinux kernel sources would turn Linus up, even though you don't want\nto send patches directly there in most of the cases. And this is\nsimply because he did the initial commit and a lot of code may not\nhave changed since that...\n\nThanks for the comments.\n\n\nVegard\n\n-- \n\"The animistic metaphor of the bug that maliciously sneaked in while\nthe programmer was not looking is intellectually dishonest as it\ndisguises that the error is the programmer's own creation.\"\n\t-- E. W. Dijkstra, EWD1036\n"}]}