Hello, I propose the attached patch. GNU tar needs it to fully implement gitignore excludes.
Best regards, Sergey PS: Please Cc: I'm not subscribed.
>From 8d8198fa1efa3e33f3712afff2e99f98d44db468 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff <[email protected]> Date: Sun, 16 Aug 2026 21:27:04 +0300 Subject: [PATCH] exclude: new function, excluded_file_name_ext The new function is similar to excluded_file_name, except that in addition to returning the boolean status, it returns also, in memory location passed as its last argument, a boolean indicating whether a matching entry was actually found in one of the exclusion segments. * lib/exclude.c (excluded_file_name_ext): New function, derived from the original excluded_file_name. * lib/exclude.h (excluded_file_name_ext): New proto. (excluded_file_name): Rewrite as a wrapper over excluded_file_name_ext. --- lib/exclude.c | 16 +++++++++------- lib/exclude.h | 7 ++++++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/exclude.c b/lib/exclude.c index 6a8604ec1b..0f5ebec2bc 100644 --- a/lib/exclude.c +++ b/lib/exclude.c @@ -458,7 +458,7 @@ file_name_matches (struct exclude_segment const *seg, char const *f, /* Return true if EX excludes F. */ bool -excluded_file_name (struct exclude const *ex, char const *f) +excluded_file_name_ext (struct exclude const *ex, char const *f, bool *pfound) { /* If no patterns are given, the default is to include. */ if (!ex->head) @@ -466,6 +466,7 @@ excluded_file_name (struct exclude const *ex, char const *f) bool invert = false; char *filename = nullptr; + bool found = false; /* Scan through the segments, reporting the status of the first match. The segments are in reverse order, so this reports the status of @@ -477,14 +478,13 @@ excluded_file_name (struct exclude const *ex, char const *f) { if (!filename) filename = xmalloc (strlen (f) + 1); - if (file_name_matches (seg, f, filename)) - break; + found = file_name_matches (seg, f, filename); } else - { - if (file_pattern_matches (seg, f)) - break; - } + found = file_pattern_matches (seg, f); + + if (found) + break; if (! seg->next) { @@ -500,6 +500,8 @@ excluded_file_name (struct exclude const *ex, char const *f) } free (filename); + if (pfound) + *pfound = found; return invert ^ ! (seg->options & EXCLUDE_INCLUDE); } diff --git a/lib/exclude.h b/lib/exclude.h index c217a1e4e6..7331003c70 100644 --- a/lib/exclude.h +++ b/lib/exclude.h @@ -68,7 +68,12 @@ int add_exclude_file (void (*) (struct exclude *, char const *, int), struct exclude *, char const *, int, char); int add_exclude_fp (void (*) (struct exclude *, char const *, int, void *), struct exclude *, FILE *, int, char, void *); -bool excluded_file_name (struct exclude const *, char const *); +bool excluded_file_name_ext (struct exclude const *, char const *, bool *); +static inline bool +excluded_file_name (struct exclude const *ex, char const *f) +{ + return excluded_file_name_ext (ex, f, NULL); +} void exclude_add_pattern_buffer (struct exclude *ex, char *buf); bool exclude_fnmatch (char const *, char const *, int); -- 2.35.1
