All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Elijah Newren <newren@gmail.com>
Cc: Yannik Tausch <dev@ytausch.de>,  git@vger.kernel.org
Subject: Re: [PATCH v2 2/2] dir: find common prefix among non-exclude pathspec items
Date: Fri, 04 Sep 2026 09:43:31 -0700	[thread overview]
Message-ID: <xmqqy0dh3r2k.fsf@gitster.g> (raw)
In-Reply-To: <CABPp-BF6hps9DibSV4ghbowkOD-NfEsHYFdLoKab0hCfEi9rgw@mail.gmail.com> (Elijah Newren's message of "Thu, 3 Sep 2026 22:02:06 -0700")

Elijah Newren <newren@gmail.com> writes:

> This to me looked more like what you are changing, and I had a hard
> time figuring out why you were changing it.

While I share this assessment,...

>
> Does the following alternative correctly capture your intent and change here? :
>
>
> dir: preserve pathspec prefix optimization with leading excludes
>
> Directory walks use the common directory prefix of non-exclude
> pathspec items to avoid scanning unrelated portions of the working
> tree or index.  Exclude items only remove paths from that candidate
> set, so they do not need to widen the traversal.
>
> When an exclude item is the first pathspec item,
> common_prefix_len() fails to establish a comparison base and returns
> a zero-length prefix.  The result is correct, but git unnecessarily
> traverses from a broader starting point even when all non-exclude
> items share a directory.

... I do not think this is true.

What happens inside dir.c::fill_directory() is driven only with the
return value of common_prefix_len(), which already ignores and has
always ignored the negative pathspec elements.

What this [2/2] changes is what string common_prefix() returns.  If
you have "!x/b" "a/b" "a/c", common_prefix_len() goes over the two
positive ones "a/b" and "a/c" and correctly notices that "a/" is
common among the positive ones and its length is 2.

The problem this patch fixes is that common_prefix() used to always
grab the first two bytes of the element that happens to be at the
beginning of pathspec, so a pathspec ("!x/b" "a/b" "a/c") would have
given you "!x" as the common prefix string, which obviously is
bogus.  The common_prefix() is only used in two code paths that are
quite distant from here.  It is clear there is a bug (i.e., the code
that wants to be passed "a/" in such a case cannot be happy to see
"!x" instead), but it is totally unclear what the end-user visible
effect of that bug (i.e. what happens when overlay_tree_on_index()
passes an incorrectly computed common_prefix() when "git ls-files"
is run with "--with-tree=<treeish>" option?).

> Use the first non-exclude item as the comparison base and return its
> string together with the prefix length, allowing callers to start
> from the recovered directory prefix.  Exclude matching continues to
> use full paths, so this restores the optimization without changing
> which paths are selected.  Add a unit test covering an exclude item
> before two non-exclude items with a common directory.

I do not think this is what this patch does.  What you are
describing is this bit:

>> -static size_t common_prefix_len(const struct pathspec *pathspec)
>> ...
>>                 size_t i = 0, len = 0, item_len;
>>                 if (pathspec->items[n].magic & PATHSPEC_EXCLUDE)
>>                         continue;

which dates back to the very beginning of negative pathspec elements
support introduced at ef79b1f870 (Support pathspec magic :(exclude)
and its short form :!, 2013-12-06), I think.

  reply	other threads:[~2026-09-04 16:43 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02 13:04 [PATCH] dir: find common prefix among positive pathspecs Yannik Tausch
2026-09-02 17:07 ` Junio C Hamano
2026-09-03  9:59   ` Yannik Tausch
2026-09-03 10:02     ` [PATCH v2 0/2] dir: fix pathspec prefixes with exclusions Yannik Tausch
2026-09-03 10:03       ` [PATCH v2 1/2] dir: do not apply prefix to negative pathspecs Yannik Tausch
2026-09-04  5:00         ` Elijah Newren
2026-09-04 14:21           ` Junio C Hamano
2026-09-03 10:04       ` [PATCH v2 2/2] dir: find common prefix among non-exclude pathspec items Yannik Tausch
     [not found]         ` <CY5PR17MB6144A1A7BF2E101FE26A6A85B1B62@CY5PR17MB6144.namprd17.prod.outlook.com>
2026-09-03 11:49           ` Yannik Tausch
2026-09-03 18:11         ` Junio C Hamano
2026-09-03 18:13           ` pathspec: match and original in pathspec_item are const Junio C Hamano
2026-09-03 18:37             ` Yannik Tausch
2026-09-03 18:51               ` Junio C Hamano
2026-09-03 18:57                 ` Yannik Tausch
2026-09-03 21:05                   ` Junio C Hamano
2026-09-03 21:13                     ` Yannik Tausch
2026-09-04  5:02         ` [PATCH v2 2/2] dir: find common prefix among non-exclude pathspec items Elijah Newren
2026-09-04 16:43           ` Junio C Hamano [this message]
2026-09-04 19:19             ` Elijah Newren
2026-09-05 16:14               ` Junio C Hamano
2026-09-03 18:06       ` [PATCH v2 0/2] dir: fix pathspec prefixes with exclusions Yannik Tausch
2026-09-03 18:43       ` [PATCH v3 0/3] " Yannik Tausch
2026-09-03 18:44         ` [PATCH v3 1/3] pathspec: match and original in pathspec_item are const Yannik Tausch
2026-09-03 18:45         ` [PATCH v3 2/3] dir: do not apply prefix to negative pathspecs Yannik Tausch
2026-09-03 18:45         ` [PATCH v3 3/3] dir: find common prefix among non-exclude pathspec items Yannik Tausch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqy0dh3r2k.fsf@gitster.g \
    --to=gitster@pobox.com \
    --cc=dev@ytausch.de \
    --cc=git@vger.kernel.org \
    --cc=newren@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.