From 72b448450142ac788c686e9bd96d5b604649a169 Mon Sep 17 00:00:00 2001
From: Jelte Fennema <jelte.fennema@microsoft.com>
Date: Fri, 10 Feb 2023 10:14:07 +0100
Subject: [PATCH] Fix pgindent commit flag and add dirty and staged flags

Fixes a bug in --commit where pgindent would try to indent deleted
files. Also implement a --staged and a --dirty flag, which were
requested by Robert Haas.
---
 src/tools/pgindent/pgindent | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/tools/pgindent/pgindent b/src/tools/pgindent/pgindent
index 07970f758c2..9245e06d04b 100755
--- a/src/tools/pgindent/pgindent
+++ b/src/tools/pgindent/pgindent
@@ -24,7 +24,7 @@ my $devnull = File::Spec->devnull;
 my ($typedefs_file, $typedef_str, $code_base,
 	@excludes,      $indent,      $build,
 	$show_diff,     $silent_diff, $help,
-	@commits,);
+	@commits,       $dirty,       $staged);
 
 $help = 0;
 
@@ -37,6 +37,8 @@ my %options = (
 	"excludes=s"         => \@excludes,
 	"indent=s"           => \$indent,
 	"build"              => \$build,
+	"dirty"              => \$dirty,
+	"staged"             => \$staged,
 	"show-diff"          => \$show_diff,
 	"silent-diff"        => \$silent_diff,);
 GetOptions(%options) || usage("bad command line argument");
@@ -60,7 +62,7 @@ $indent ||= $ENV{PGINDENT} || $ENV{INDENT} || "pg_bsd_indent";
 
 # if no non-option arguments or commits are given, default to looking in the
 # current directory
-$code_base ||= '.' unless (@ARGV || @commits);
+$code_base ||= '.' unless (@ARGV || @commits || $dirty || $staged);
 
 my $sourcedir = locate_sourcedir();
 
@@ -401,6 +403,8 @@ Options:
 	--excludes=PATH         file containing list of filename patterns to ignore
 	--indent=PATH           path to pg_bsd_indent program
 	--build                 build the pg_bsd_indent program
+	--staged                use files that are staged for commit
+	--dirty                 use files that are modified (but not staged)
 	--show-diff             show the changes that would be made
 	--silent-diff           exit with status 2 if any changes would be made
 The --excludes and --commit options can be given more than once.
@@ -444,7 +448,23 @@ File::Find::find({wanted => $wanted}, @ARGV) if @ARGV;
 foreach my $commit (@commits)
 {
 	my $prev="$commit~";
-	my @affected=`git diff-tree --no-commit-id --name-only -r $commit $prev`;
+	my @affected=`git diff --diff-filter=ACMR --name-only $prev $commit`;
+	die "git error" if $?;
+	chomp(@affected);
+	push(@files,@affected);
+}
+
+if ($staged)
+{
+	my @affected=`git diff --diff-filter=ACMR --name-only --staged`;
+	die "git error" if $?;
+	chomp(@affected);
+	push(@files,@affected);
+}
+
+if ($dirty)
+{
+	my @affected=`git diff --diff-filter=ACMR --name-only`;
 	die "git error" if $?;
 	chomp(@affected);
 	push(@files,@affected);
-- 
2.34.1

