contrib: add git-contacts helper
This script lists people that might be interested in a patch by going
back through the history for each patch hunk, and finding people that
reviewed, acknowledged, signed, authored, or were Cc:'d on the code the
patch is modifying.
It does this by running git-blame incrementally on each hunk and then
parsing the commit message. After gathering all participants, it
determines each person's relevance by considering how many commits
mentioned that person compared with the total number of commits under
consideration. The final output consists only of participants who pass a
minimum threshold of participation.
Several conditions controlling a person's significance are currently
hard-coded, such as minimum participation level, blame date-limiting,
and -C level for detecting moved and copied lines. In the future, these
conditions may become configurable.
For example:
% git contacts 0001-remote-hg-trivial-cleanups.patch
Felipe Contreras <felipe.contreras@gmail.com>
Jeff King <peff@peff.net>
Max Horn <max@quendi.de>
Junio C Hamano <gitster@pobox.com>
Thus, it can be invoked as git-send-email's --cc-cmd option, among other
possible uses.
This is a Perl rewrite of Felipe Contreras' git-related patch series[1]
written in Ruby.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/226065/
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-21 12:52:38 +02:00
|
|
|
#!/usr/bin/perl
|
|
|
|
|
|
|
|
# List people who might be interested in a patch. Useful as the argument to
|
|
|
|
# git-send-email --cc-cmd option, and in other situations.
|
|
|
|
#
|
2013-07-21 12:52:39 +02:00
|
|
|
# Usage: git contacts <file | rev-list option> ...
|
contrib: add git-contacts helper
This script lists people that might be interested in a patch by going
back through the history for each patch hunk, and finding people that
reviewed, acknowledged, signed, authored, or were Cc:'d on the code the
patch is modifying.
It does this by running git-blame incrementally on each hunk and then
parsing the commit message. After gathering all participants, it
determines each person's relevance by considering how many commits
mentioned that person compared with the total number of commits under
consideration. The final output consists only of participants who pass a
minimum threshold of participation.
Several conditions controlling a person's significance are currently
hard-coded, such as minimum participation level, blame date-limiting,
and -C level for detecting moved and copied lines. In the future, these
conditions may become configurable.
For example:
% git contacts 0001-remote-hg-trivial-cleanups.patch
Felipe Contreras <felipe.contreras@gmail.com>
Jeff King <peff@peff.net>
Max Horn <max@quendi.de>
Junio C Hamano <gitster@pobox.com>
Thus, it can be invoked as git-send-email's --cc-cmd option, among other
possible uses.
This is a Perl rewrite of Felipe Contreras' git-related patch series[1]
written in Ruby.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/226065/
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-21 12:52:38 +02:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use IPC::Open2;
|
|
|
|
|
|
|
|
my $since = '5-years-ago';
|
|
|
|
my $min_percent = 10;
|
|
|
|
my $labels_rx = qr/Signed-off-by|Reviewed-by|Acked-by|Cc/i;
|
|
|
|
my %seen;
|
|
|
|
|
|
|
|
sub format_contact {
|
|
|
|
my ($name, $email) = @_;
|
|
|
|
return "$name <$email>";
|
|
|
|
}
|
|
|
|
|
|
|
|
sub parse_commit {
|
|
|
|
my ($commit, $data) = @_;
|
|
|
|
my $contacts = $commit->{contacts};
|
|
|
|
my $inbody = 0;
|
|
|
|
for (split(/^/m, $data)) {
|
|
|
|
if (not $inbody) {
|
|
|
|
if (/^author ([^<>]+) <(\S+)> .+$/) {
|
|
|
|
$contacts->{format_contact($1, $2)} = 1;
|
|
|
|
} elsif (/^$/) {
|
|
|
|
$inbody = 1;
|
|
|
|
}
|
|
|
|
} elsif (/^$labels_rx:\s+([^<>]+)\s+<(\S+?)>$/o) {
|
|
|
|
$contacts->{format_contact($1, $2)} = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub import_commits {
|
|
|
|
my ($commits) = @_;
|
|
|
|
return unless %$commits;
|
|
|
|
my $pid = open2 my $reader, my $writer, qw(git cat-file --batch);
|
|
|
|
for my $id (keys(%$commits)) {
|
|
|
|
print $writer "$id\n";
|
|
|
|
my $line = <$reader>;
|
|
|
|
if ($line =~ /^([0-9a-f]{40}) commit (\d+)/) {
|
|
|
|
my ($cid, $len) = ($1, $2);
|
|
|
|
die "expected $id but got $cid\n" unless $id eq $cid;
|
|
|
|
my $data;
|
|
|
|
# cat-file emits newline after data, so read len+1
|
|
|
|
read $reader, $data, $len + 1;
|
|
|
|
parse_commit($commits->{$id}, $data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close $reader;
|
|
|
|
close $writer;
|
|
|
|
waitpid($pid, 0);
|
|
|
|
die "git-cat-file error: $?\n" if $?;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub get_blame {
|
|
|
|
my ($commits, $source, $start, $len, $from) = @_;
|
|
|
|
$len = 1 unless defined($len);
|
|
|
|
return if $len == 0;
|
|
|
|
open my $f, '-|',
|
|
|
|
qw(git blame --porcelain -C), '-L', "$start,+$len",
|
|
|
|
'--since', $since, "$from^", '--', $source or die;
|
|
|
|
while (<$f>) {
|
|
|
|
if (/^([0-9a-f]{40}) \d+ \d+ \d+$/) {
|
|
|
|
my $id = $1;
|
|
|
|
$commits->{$id} = { id => $id, contacts => {} }
|
|
|
|
unless $seen{$id};
|
|
|
|
$seen{$id} = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close $f;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub scan_patches {
|
2013-07-21 12:52:39 +02:00
|
|
|
my ($commits, $id, $f) = @_;
|
|
|
|
my $source;
|
contrib: add git-contacts helper
This script lists people that might be interested in a patch by going
back through the history for each patch hunk, and finding people that
reviewed, acknowledged, signed, authored, or were Cc:'d on the code the
patch is modifying.
It does this by running git-blame incrementally on each hunk and then
parsing the commit message. After gathering all participants, it
determines each person's relevance by considering how many commits
mentioned that person compared with the total number of commits under
consideration. The final output consists only of participants who pass a
minimum threshold of participation.
Several conditions controlling a person's significance are currently
hard-coded, such as minimum participation level, blame date-limiting,
and -C level for detecting moved and copied lines. In the future, these
conditions may become configurable.
For example:
% git contacts 0001-remote-hg-trivial-cleanups.patch
Felipe Contreras <felipe.contreras@gmail.com>
Jeff King <peff@peff.net>
Max Horn <max@quendi.de>
Junio C Hamano <gitster@pobox.com>
Thus, it can be invoked as git-send-email's --cc-cmd option, among other
possible uses.
This is a Perl rewrite of Felipe Contreras' git-related patch series[1]
written in Ruby.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/226065/
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-21 12:52:38 +02:00
|
|
|
while (<$f>) {
|
|
|
|
if (/^From ([0-9a-f]{40}) Mon Sep 17 00:00:00 2001$/) {
|
|
|
|
$id = $1;
|
|
|
|
$seen{$id} = 1;
|
|
|
|
}
|
|
|
|
next unless $id;
|
|
|
|
if (m{^--- (?:a/(.+)|/dev/null)$}) {
|
|
|
|
$source = $1;
|
|
|
|
} elsif (/^--- /) {
|
|
|
|
die "Cannot parse hunk source: $_\n";
|
|
|
|
} elsif (/^@@ -(\d+)(?:,(\d+))?/ && $source) {
|
|
|
|
get_blame($commits, $source, $1, $2, $id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub scan_patch_file {
|
|
|
|
my ($commits, $file) = @_;
|
|
|
|
open my $f, '<', $file or die "read failure: $file: $!\n";
|
2013-07-21 12:52:39 +02:00
|
|
|
scan_patches($commits, undef, $f);
|
|
|
|
close $f;
|
|
|
|
}
|
|
|
|
|
2013-07-21 12:52:40 +02:00
|
|
|
sub parse_rev_args {
|
|
|
|
my @args = @_;
|
|
|
|
open my $f, '-|',
|
|
|
|
qw(git rev-parse --revs-only --default HEAD --symbolic), @args
|
|
|
|
or die;
|
|
|
|
my @revs;
|
|
|
|
while (<$f>) {
|
|
|
|
chomp;
|
|
|
|
push @revs, $_;
|
|
|
|
}
|
|
|
|
close $f;
|
|
|
|
return @revs if scalar(@revs) != 1;
|
|
|
|
return "^$revs[0]", 'HEAD' unless $revs[0] =~ /^-/;
|
|
|
|
return $revs[0], 'HEAD';
|
|
|
|
}
|
|
|
|
|
2013-07-21 12:52:39 +02:00
|
|
|
sub scan_rev_args {
|
|
|
|
my ($commits, $args) = @_;
|
2013-07-21 12:52:40 +02:00
|
|
|
my @revs = parse_rev_args(@$args);
|
|
|
|
open my $f, '-|', qw(git rev-list --reverse), @revs or die;
|
2013-07-21 12:52:39 +02:00
|
|
|
while (<$f>) {
|
|
|
|
chomp;
|
|
|
|
my $id = $_;
|
|
|
|
$seen{$id} = 1;
|
|
|
|
open my $g, '-|', qw(git show -C --oneline), $id or die;
|
|
|
|
scan_patches($commits, $id, $g);
|
|
|
|
close $g;
|
|
|
|
}
|
contrib: add git-contacts helper
This script lists people that might be interested in a patch by going
back through the history for each patch hunk, and finding people that
reviewed, acknowledged, signed, authored, or were Cc:'d on the code the
patch is modifying.
It does this by running git-blame incrementally on each hunk and then
parsing the commit message. After gathering all participants, it
determines each person's relevance by considering how many commits
mentioned that person compared with the total number of commits under
consideration. The final output consists only of participants who pass a
minimum threshold of participation.
Several conditions controlling a person's significance are currently
hard-coded, such as minimum participation level, blame date-limiting,
and -C level for detecting moved and copied lines. In the future, these
conditions may become configurable.
For example:
% git contacts 0001-remote-hg-trivial-cleanups.patch
Felipe Contreras <felipe.contreras@gmail.com>
Jeff King <peff@peff.net>
Max Horn <max@quendi.de>
Junio C Hamano <gitster@pobox.com>
Thus, it can be invoked as git-send-email's --cc-cmd option, among other
possible uses.
This is a Perl rewrite of Felipe Contreras' git-related patch series[1]
written in Ruby.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/226065/
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-21 12:52:38 +02:00
|
|
|
close $f;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!@ARGV) {
|
2013-07-21 12:52:39 +02:00
|
|
|
die "No input revisions or patch files\n";
|
contrib: add git-contacts helper
This script lists people that might be interested in a patch by going
back through the history for each patch hunk, and finding people that
reviewed, acknowledged, signed, authored, or were Cc:'d on the code the
patch is modifying.
It does this by running git-blame incrementally on each hunk and then
parsing the commit message. After gathering all participants, it
determines each person's relevance by considering how many commits
mentioned that person compared with the total number of commits under
consideration. The final output consists only of participants who pass a
minimum threshold of participation.
Several conditions controlling a person's significance are currently
hard-coded, such as minimum participation level, blame date-limiting,
and -C level for detecting moved and copied lines. In the future, these
conditions may become configurable.
For example:
% git contacts 0001-remote-hg-trivial-cleanups.patch
Felipe Contreras <felipe.contreras@gmail.com>
Jeff King <peff@peff.net>
Max Horn <max@quendi.de>
Junio C Hamano <gitster@pobox.com>
Thus, it can be invoked as git-send-email's --cc-cmd option, among other
possible uses.
This is a Perl rewrite of Felipe Contreras' git-related patch series[1]
written in Ruby.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/226065/
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-21 12:52:38 +02:00
|
|
|
}
|
|
|
|
|
2013-07-21 12:52:39 +02:00
|
|
|
my (@files, @rev_args);
|
contrib: add git-contacts helper
This script lists people that might be interested in a patch by going
back through the history for each patch hunk, and finding people that
reviewed, acknowledged, signed, authored, or were Cc:'d on the code the
patch is modifying.
It does this by running git-blame incrementally on each hunk and then
parsing the commit message. After gathering all participants, it
determines each person's relevance by considering how many commits
mentioned that person compared with the total number of commits under
consideration. The final output consists only of participants who pass a
minimum threshold of participation.
Several conditions controlling a person's significance are currently
hard-coded, such as minimum participation level, blame date-limiting,
and -C level for detecting moved and copied lines. In the future, these
conditions may become configurable.
For example:
% git contacts 0001-remote-hg-trivial-cleanups.patch
Felipe Contreras <felipe.contreras@gmail.com>
Jeff King <peff@peff.net>
Max Horn <max@quendi.de>
Junio C Hamano <gitster@pobox.com>
Thus, it can be invoked as git-send-email's --cc-cmd option, among other
possible uses.
This is a Perl rewrite of Felipe Contreras' git-related patch series[1]
written in Ruby.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/226065/
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-21 12:52:38 +02:00
|
|
|
for (@ARGV) {
|
2013-07-21 12:52:39 +02:00
|
|
|
if (-e) {
|
|
|
|
push @files, $_;
|
|
|
|
} else {
|
|
|
|
push @rev_args, $_;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
my %commits;
|
|
|
|
for (@files) {
|
contrib: add git-contacts helper
This script lists people that might be interested in a patch by going
back through the history for each patch hunk, and finding people that
reviewed, acknowledged, signed, authored, or were Cc:'d on the code the
patch is modifying.
It does this by running git-blame incrementally on each hunk and then
parsing the commit message. After gathering all participants, it
determines each person's relevance by considering how many commits
mentioned that person compared with the total number of commits under
consideration. The final output consists only of participants who pass a
minimum threshold of participation.
Several conditions controlling a person's significance are currently
hard-coded, such as minimum participation level, blame date-limiting,
and -C level for detecting moved and copied lines. In the future, these
conditions may become configurable.
For example:
% git contacts 0001-remote-hg-trivial-cleanups.patch
Felipe Contreras <felipe.contreras@gmail.com>
Jeff King <peff@peff.net>
Max Horn <max@quendi.de>
Junio C Hamano <gitster@pobox.com>
Thus, it can be invoked as git-send-email's --cc-cmd option, among other
possible uses.
This is a Perl rewrite of Felipe Contreras' git-related patch series[1]
written in Ruby.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/226065/
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-21 12:52:38 +02:00
|
|
|
scan_patch_file(\%commits, $_);
|
|
|
|
}
|
2013-07-21 12:52:39 +02:00
|
|
|
if (@rev_args) {
|
|
|
|
scan_rev_args(\%commits, \@rev_args)
|
|
|
|
}
|
contrib: add git-contacts helper
This script lists people that might be interested in a patch by going
back through the history for each patch hunk, and finding people that
reviewed, acknowledged, signed, authored, or were Cc:'d on the code the
patch is modifying.
It does this by running git-blame incrementally on each hunk and then
parsing the commit message. After gathering all participants, it
determines each person's relevance by considering how many commits
mentioned that person compared with the total number of commits under
consideration. The final output consists only of participants who pass a
minimum threshold of participation.
Several conditions controlling a person's significance are currently
hard-coded, such as minimum participation level, blame date-limiting,
and -C level for detecting moved and copied lines. In the future, these
conditions may become configurable.
For example:
% git contacts 0001-remote-hg-trivial-cleanups.patch
Felipe Contreras <felipe.contreras@gmail.com>
Jeff King <peff@peff.net>
Max Horn <max@quendi.de>
Junio C Hamano <gitster@pobox.com>
Thus, it can be invoked as git-send-email's --cc-cmd option, among other
possible uses.
This is a Perl rewrite of Felipe Contreras' git-related patch series[1]
written in Ruby.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/226065/
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-21 12:52:38 +02:00
|
|
|
import_commits(\%commits);
|
|
|
|
|
|
|
|
my $contacts = {};
|
|
|
|
for my $commit (values %commits) {
|
|
|
|
for my $contact (keys %{$commit->{contacts}}) {
|
|
|
|
$contacts->{$contact}++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
my $ncommits = scalar(keys %commits);
|
|
|
|
for my $contact (keys %$contacts) {
|
|
|
|
my $percent = $contacts->{$contact} * 100 / $ncommits;
|
|
|
|
next if $percent < $min_percent;
|
|
|
|
print "$contact\n";
|
|
|
|
}
|