On Thu, Sep 20, 2007 at 02:12:54PM +0100, Johannes Schindelin wrote: > Further, it probably makes sense to have the option to say _both_: "Find > me a commit that contains Bart in one line, but not Simpson, and that > does not contain the word "Sverdoolaege" at all." This is perhaps a little hack-ish compared to better grep support in the core, but I find complex logic through command line options to be somewhat unreadable. I prefer something more Perl-ish like this: git-revgrep 'message =~ /bart/i && message !~ /Simpson/ && author_name !~ /Sverdoolaege/' or if you want to get complex: git-revgrep ' return 0 if message =~ /Sverdoolaege/; while(my $line = message =~ /^(.*bart.*)/gmi) { return 1 if $line !~ /Simpson/; } return 0;' where revgrep is the script below: -- >8 -- #!/usr/bin/perl use strict; my $matcher = shift || ''; my $matcher_sub = eval "sub { $matcher }"; die $@ if $@; my $input = do { if(@ARGV == 1 && $ARGV[0] eq '-') { \*STDIN; } else { open(my $fh, '-|', qw(git log --pretty=raw), @ARGV) or die "unable to open pipe to git log: $!"; $fh; } }; our $commit; while(<$input>) { if(/^commit /) { try_match() if $commit; $commit = $_; } else { $commit .= $_; } } try_match() if $commit; exit 0; sub try_match { if($matcher_sub->()) { print STDOUT $commit; } } sub parse_person { $_[0] =~ /([^<]*) <([^>]*)> (.*)/ } sub parse_author { return parse_person($commit =~ /^author (.*)/m) } sub parse_committer { return parse_person($commit =~ /^committer (.*)/m) } sub author_name { return (parse_author)[0] } sub author_email { return (parse_author)[1] } sub author_time { return (parse_author)[2] } sub committer_name { return (parse_committer)[0] } sub committer_email { return (parse_committer)[1] } sub committer_time { return (parse_committer)[2] } sub message { return ($commit =~ /^( +.*?^$)/ms)[0] } - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html