document count option (and imply unique)
[git-grep-footer.git] / git-grep-footer
index 0c26549197cfddfa4eeb8e511edd4aab1134dcde..b676ab8aef983e241ffb59921849d94075dd889d 100755 (executable)
@@ -23,12 +23,12 @@ GetOptions(\my %opt,
 local $| = 1;
 local $/ = "\0";
 
 local $| = 1;
 local $/ = "\0";
 
-my $HEADERMATCH = qr/ [a-z]+ (?: (?:-\w+)+ | \ by ) /ix;
+my $HEADERMATCH = qr/ [a-z]+ (?: (?:-\w+)+ | \ by ) | cc | reference /ix;
 
 my (%headercount, @headercache);
 
 while (readline) {
 
 my (%headercount, @headercache);
 
 while (readline) {
-       s/(.+)\n//m;
+       s/^([0-9a-f]{4,40})\n//m and
        my $hash = $1;
 
        # strip commit seperator
        my $hash = $1;
 
        # strip commit seperator
@@ -40,12 +40,12 @@ while (readline) {
        # if invalid, assume it's latin1
               $_ = decode(cp1252 => $_) if $@;
 
        # if invalid, assume it's latin1
               $_ = decode(cp1252 => $_) if $@;
 
-       my $prefix = 0;
        my %attr;
 
        BLOCK:
        for (reverse split /\n\n/) {
                my @headers;
        my %attr;
 
        BLOCK:
        for (reverse split /\n\n/) {
                my @headers;
+               my $prefix = 0;
 
                LINE:
                for (split /\n/) {
 
                LINE:
                for (split /\n/) {
@@ -85,7 +85,7 @@ while (readline) {
                                        }{<...>}imsx;
                                }
                                when (['var', 'vars', '']) {
                                        }{<...>}imsx;
                                }
                                when (['var', 'vars', '']) {
-                                       when ($header[0] =~ /[ _-] (?: by | to ) $/imsx) {
+                                       when ($header[0] =~ /[ _-] (?: by | to ) $ | ^cc$/imsx) {
                                                $header[1] = undef;
                                        }
                                        for ($header[1]) {
                                                $header[1] = undef;
                                        }
                                        for ($header[1]) {
@@ -118,12 +118,14 @@ while (readline) {
                next BLOCK if not @headers;
 
                if ($opt{debug} and $prefix) {
                next BLOCK if not @headers;
 
                if ($opt{debug} and $prefix) {
-                       say "infix junk in commit $hash";
+                       say sprintf ': invalid lines in %s (%s)', $hash // 'block', $prefix;
                }
 
                for (@headers) {
                        my $line = $_->[2] // join(': ', @$_);
                }
 
                for (@headers) {
                        my $line = $_->[2] // join(': ', @$_);
-                       if (defined $opt{min} or $opt{max}) {
+                       $line =~ s/^/$hash / if defined $hash;
+
+                       if (defined $opt{min} or $opt{max} or $opt{count}) {
                                my $counter = \$headercount{ $_->[0] }->{ $_->[1] // '' };
                                my $excess = $$counter++ - ($opt{min} // 0);
                                next if $excess >= ($opt{max} || 1);
                                my $counter = \$headercount{ $_->[0] }->{ $_->[1] // '' };
                                my $excess = $$counter++ - ($opt{min} // 0);
                                next if $excess >= ($opt{max} || 1);
@@ -161,6 +163,7 @@ a common convention to list custom metadata such as
 C<Signed-off-by> and C<Acked-by>.
 
 Sections are identified by at least one leading keyword containing a dash
 C<Signed-off-by> and C<Acked-by>.
 
 Sections are identified by at least one leading keyword containing a dash
+(or exceptionally recognised)
 followed by a colon.
 
 =head1 OPTIONS
 followed by a colon.
 
 =head1 OPTIONS
@@ -208,6 +211,11 @@ The original line is given for each match,
 but simplifications still apply for duplicate determination.
 Additional samples are optionally given upto the given maximum.
 
 but simplifications still apply for duplicate determination.
 Additional samples are optionally given upto the given maximum.
 
+=item -c, --count
+
+Prefixes (unique) lines by the number of occurrences.
+Causes output to be buffered until all input has been read (obviously).
+
 =back
 
 =head1 AUTHOR
 =back
 
 =head1 AUTHOR