git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] dir: find common prefix among positive pathspecs

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 2, 2026, 17:07 UTC
Message-ID
<xmqqecfbk2eb.fsf@gitster.g>
In-Reply-To
<AA085B7A-F528-458A-8AA9-7664480997AE@ytausch.de>
Yannik Tausch <dev@ytausch.de> writes:
Show 14 quoted lines
> common_prefix_len() skips exclude pathspec items, but uses n == 0 to
> identify the initial item and items[0] as the comparison source. When
> an exclude item comes first, the function returns zero even when all
> positive pathspecs share a directory.
>
> Track the first positive item explicitly. Return its match and the
> common prefix length together so that common_prefix() and
> fill_directory() use the correct string. Add a unit test with an
> unrelated exclude before two positive pathspecs that share a directory.
>
> Signed-off-by: Yannik Tausch <dev@ytausch.de>
> ---
>
> This patch is based on https://lore.kernel.org/git/0CA8678D-0540-4A2E-B314-B9BEB04E2BF5@ytausch.de/T/#u.

I am not sure what you mean. Do you mean that the other one should have been marked as [PATCH 1/2] and this one [PATCH 2/2]? The way we use the phrase "based on" does not exactly match that situation. It is more like "This patch applies on top of the other one", or "This patch depends on the other one."

Show 11 quoted lines
> -static size_t common_prefix_len(const struct pathspec *pathspec)
> +struct pathspec_prefix {
> +	const char *match;
> +	size_t len;
> +};
> +
> +/*
> + * Find the common prefix of positive pathspec items. The returned match
> + * points into the first positive item and is not NUL-terminated at len.
> + */
> +static struct pathspec_prefix find_common_prefix(const struct pathspec *pathspec)

Our norm in C is not to pass structures by value either as parameter of as return value, unless there is a very good reason to do so.

Since we can easily use
	const char *common_prefix(const sturct pathspec *pathspec, size_t *len);

to return .match and store the length in *len when we return, we cannot say that this case has a very good reason to use a structure passed by value.

Actually, I have a feeling that we do not want find_common_prefix() helper. Instead perhaps

    static size_t common_prefix_len(const struct pathspec *pathspec,
				    const char **matched_prefix)

may be an alternative that is easier to work with. Because the existing callers assume that pathspec->items[0].match is where they can grab the common prefix from, they should look like

	len = common_prefix_len(pathspec);
	... use the first len bytes of pathspec->items[0].match[] ...
They want to be told to do this instead now:
	const char *common_prefix;
	len = common_prefix_len(pathspec, &common_prefix);
	... use the first len bytes of common_prefix[] ...

In "use the first len bytes" logic they already have, they know not to memdup when len == 0 (and ignore pathspec->items[0].match[] in that case), and they know they need to memdup if they want to have their own copies, etc., so the changes to them can be kept to the minimum.

> +	prefix.match = first < 0 ? NULL : pathspec->items[first].match;
> +	prefix.len = max;
> +	return prefix;
So instead of these three lines, your return sequence would become
	*matched_prefix = first < 0 ? NULL : pathspec->items[first].match;
	return max;

If there is no positive element in the given pathspec (by the way, "pathspec" refers to the whole set, and each element in it may be either positive or negative, so "positive pathspec(s)" is a misnomer), the loop never touches first or max, so when the loop exits, we won't have "match" and "len" is 0. Your changes in the loop to avoid assuming [0] is positive element all look correct.

Previous: Yannik TauschNext: Yannik Tausch
Message 2 of 29 in “dir: find common prefix among positive pathspecs”
  1. dir: find common prefix among positive pathspecsYannik Tausch, Sep 2, 2026
  2. Junio C HamanoSep 2, 2026
  3. Yannik TauschSep 3, 2026
  4. 0/2 dir: fix pathspec prefixes with exclusionsYannik Tausch, Sep 3, 2026
  5. 1/2 dir: do not apply prefix to negative pathspecsYannik Tausch, Sep 3, 2026
  6. Elijah NewrenSep 4, 2026
  7. Junio C HamanoSep 4, 2026
  8. 2/2 dir: find common prefix among non-exclude pathspec itemsYannik Tausch, Sep 3, 2026
  9. Junio C HamanoSep 3, 2026
  10. pathspec: match and original in pathspec_item are constJunio C Hamano, Sep 3, 2026
  11. Yannik TauschSep 3, 2026
  12. Junio C HamanoSep 3, 2026
  13. Yannik TauschSep 3, 2026
  14. Junio C HamanoSep 3, 2026
  15. Yannik TauschSep 3, 2026
  16. Elijah NewrenSep 4, 2026
  17. Junio C HamanoSep 4, 2026
  18. Elijah NewrenSep 4, 2026
  19. Junio C HamanoSep 5, 2026
  20. Yannik TauschSep 3, 2026
  21. 0/3 dir: fix pathspec prefixes with exclusionsYannik Tausch, Sep 3, 2026
  22. 1/3 pathspec: match and original in pathspec_item are constYannik Tausch, Sep 3, 2026
  23. 2/3 dir: do not apply prefix to negative pathspecsYannik Tausch, Sep 3, 2026
  24. 3/3 dir: find common prefix among non-exclude pathspec itemsYannik Tausch, Sep 3, 2026
  25. 0/2 dir: fix pathspec prefixes with exclusionsYannik Tausch, Sep 14, 2026
  26. 1/2 dir: do not apply prefix to negative pathspecsYannik Tausch, Sep 14, 2026
  27. 2/2 dir: preserve pathspec prefix optimization with leading excludesYannik Tausch, Sep 14, 2026
  28. Junio C HamanoSep 16, 2026
  29. Yannik TauschSep 3, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.