From ae515e0d4a848da800ecf7e7743902a80a2344ea Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <postgres@jeltef.nl>
Date: Tue, 3 Mar 2026 09:43:33 +0100
Subject: [PATCH v3 3/8] pgindent: Use git ls-files to discover files

When running pgindent on the whole source tree, it would often also
indent build artifacts. This changes the pgindent directory search logic
to become git-aware, and only indent files that are actually tracked by
git.

Any files that are explicitly part of the pgindent its arguments, are
always indented though, even if they are not tracked by git. This can be
useful to force indentation of an untracked file and/or for editor
integration.
---
 src/tools/pgindent/pgindent | 44 +++++++++++++++++++++++++++++--------
 1 file changed, 35 insertions(+), 9 deletions(-)

diff --git a/src/tools/pgindent/pgindent b/src/tools/pgindent/pgindent
index 6ce695895eb..b6fbda9a298 100755
--- a/src/tools/pgindent/pgindent
+++ b/src/tools/pgindent/pgindent
@@ -13,7 +13,6 @@ use strict;
 use warnings FATAL => 'all';
 
 use Cwd qw(abs_path getcwd);
-use File::Find;
 use File::Spec;
 use File::Temp;
 use IO::Handle;
@@ -369,16 +368,43 @@ $filtered_typedefs_fh = load_typedefs();
 
 check_indent();
 
-my $wanted = sub {
-	my ($dev, $ino, $mode, $nlink, $uid, $gid);
-	(($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_))
-	  && -f _
-	  && /^.*\.[ch]\z/s
-	  && push(@files, $File::Find::name);
-};
+sub discover_files
+{
+	my @paths = @_;
+	my @discovered;
+
+	# Separate individual files from directories
+	my @dirs;
+	foreach my $path (@paths)
+	{
+		if (-f $path)
+		{
+			push(@discovered, $path);
+		}
+		elsif (-d $path)
+		{
+			push(@dirs, $path);
+		}
+		else
+		{
+			warn "Could not find $path";
+		}
+	}
+
+	# Use git ls-files for directories to avoid searching build trees etc.
+	if (@dirs)
+	{
+		my @git_files = `git ls-files -- @dirs`;
+		die "git ls-files error" if $?;
+		chomp(@git_files);
+		push(@discovered, grep { /\.[ch]$/ } @git_files);
+	}
+
+	return @discovered;
+}
 
 # any non-option arguments are files or directories to be processed
-File::Find::find({ wanted => $wanted }, @ARGV) if @ARGV;
+push(@files, discover_files(@ARGV)) if @ARGV;
 
 # commit file locations are relative to the source root
 chdir "$sourcedir/../../.." if @commits && $sourcedir;
-- 
2.53.0

