@@ -23,12 +23,14 @@ my $devnull = File::Spec->devnull;
2323
2424my ($typedefs_file ,$typedef_str ,$code_base ,
2525@excludes ,$indent ,$build ,
26- $show_diff ,$silent_diff ,$help );
26+ $show_diff ,$silent_diff ,$help ,
27+ @commits ,);
2728
2829$help = 0;
2930
3031my %options = (
3132" help" => \$help ,
33+ " commit=s" => \@commits ,
3234" typedefs=s" => \$typedefs_file ,
3335" list-of-typedefs=s" => \$typedef_str ,
3436" code-base=s" => \$code_base ,
@@ -44,6 +46,9 @@ usage() if $help;
4446usage(" Cannot have both --silent-diff and --show-diff" )
4547if $silent_diff &&$show_diff ;
4648
49+ usage(" Cannot use --commit with --code-base or command line file list" )
50+ if (@commits && ($code_base ||@ARGV ));
51+
4752run_build($code_base )if ($build );
4853
4954# command line option wins, then environment (which is how --build sets it) ,
@@ -53,8 +58,9 @@ $typedefs_file ||= $ENV{PGTYPEDEFS};
5358# build mode sets PGINDENT
5459$indent ||=$ENV {PGINDENT } ||$ENV {INDENT } ||" pg_bsd_indent" ;
5560
56- # no non-option arguments given. so do everything in the current directory
57- $code_base ||=' .' unless @ARGV ;
61+ # if no non-option arguments or commits are given, default to looking in the
62+ # current directory
63+ $code_base ||=' .' unless (@ARGV ||@commits );
5864
5965my $sourcedir = locate_sourcedir();
6066
@@ -388,6 +394,7 @@ Usage:
388394pgindent [OPTION]... [FILE]...
389395Options:
390396--help show this message and quit
397+ --commit=gitref use files modified by the named commit
391398--typedefs=FILE file containing a list of typedefs
392399--list-of-typedefs=STR string containing typedefs, space separated
393400--code-base=DIR path to the base of PostgreSQL source code
@@ -396,7 +403,7 @@ Options:
396403--build build the pg_bsd_indent program
397404--show-diff show the changes that would be made
398405--silent-diff exit with status 2 if any changes would be made
399- The --excludesoption can be given more than once.
406+ The --excludesand --commit options can be given more than once.
400407EOF
401408if ($help )
402409{
@@ -412,27 +419,38 @@ EOF
412419
413420# main
414421
415- # get the list of files under code base, if it's set
416- File::Find::find(
417- {
418- wanted => sub {
419- my ($dev ,$ino ,$mode ,$nlink ,$uid ,$gid );
420- (($dev ,$ino ,$mode ,$nlink ,$uid ,$gid ) =lstat ($_ ))
421- &&-f _
422- &&/ ^.*\. [ch]\z /s
423- &&push (@files ,$File::Find::name );
424- }
425- },
426- $code_base )if $code_base ;
427-
428422$filtered_typedefs_fh = load_typedefs();
429423
430424check_indent();
431425
432- # any non-option arguments are files to be processed
433- push (@files ,@ARGV );
426+ build_clean($code_base )if $build ;
427+
428+ my $wanted =sub
429+ {
430+ my ($dev ,$ino ,$mode ,$nlink ,$uid ,$gid );
431+ (($dev ,$ino ,$mode ,$nlink ,$uid ,$gid ) =lstat ($_ ))
432+ &&-f _
433+ &&/ ^.*\. [ch]\z /s
434+ &&push (@files ,$File::Find::name );
435+ };
436+
437+ # get the list of files under code base, if it's set
438+ File::Find::find({wanted => $wanted },$code_base )if $code_base ;
439+
440+ # any non-option arguments are files or directories to be processed
441+ File::Find::find({wanted => $wanted },@ARGV )if @ARGV ;
442+
443+ # process named commits by comparing each with their immediate ancestor
444+ foreach my $commit (@commits )
445+ {
446+ my $prev =" $commit ~" ;
447+ my @affected =` git diff-tree --no-commit-id --name-only -r$commit $prev ` ;
448+ die " git error" if $? ;
449+ chomp (@affected );
450+ push (@files ,@affected );
451+ }
434452
435- # the exclude list applies to command line arguments as well as found files
453+ # remove excluded files from the file list
436454process_exclude();
437455
438456foreach my $source_filename (@files )
@@ -481,6 +499,4 @@ foreach my $source_filename (@files)
481499}
482500}
483501
484- build_clean($code_base )if $build ;
485-
486502exit 0;