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

Re: [PATCH] doc: document backslash in gitignore patterns

From
Jeff King <peff@peff.net>
Date
Oct 30, 2025, 15:08 UTC
Message-ID
<20251030150814.GA1275070@coredump.intra.peff.net>
In-Reply-To
<CALnO6CButUc89H0a+FrrdY4pWh10=U8yeWfd7Oesb=1wpHMmSg@mail.gmail.com>
On Thu, Oct 30, 2025 at 09:40:36AM -0400, D. Ben Knoble wrote:
Show 10 quoted lines
> > There's also the "pathspec" entry in gitglossary(7), which does mention
> > fnmatch(3). Though it is even more confusing because of the literal
> > matching that pathspecs do. I don't know if we'd want anything there
> > (and I kind of doubt people get as exotic about patterns there as they
> > would in gitignore).
>
> I certainly wondered about the pathspec case, since the commit message
> called out the difference in behavior. For example, at least in this
> one corner, we can't reliably use Git commands with pathspecs to build
> up example gitignore patterns to throw in .gitignore?

They're close enough that I suspect people do use them interchangeably, but there are definitely important corner cases. Like the anchoring stuff below.

Show 9 quoted lines
> BTW, is the literal matching intended to be conveyed by
> 
>            •   any path matches itself
> 
> ? If so, I'm not quite sure how to interpret a pathspec like a/b given
> a repo with a/b and dir/a/b—do both match or only the former? I expect
> in combination with the 2 subsequent bullets that only the former
> matches. Conversely, with a pathspec "b" in that case, I think I could
> read the docs as suggesting both match, when IIRC none do. Hm!

I may not be the right person to ask, as I wasn't aware of the literal match behavior here until I tried to write that wildmatch test, and then walked it through the debugger. ;) Finding the documentation justification came later.

But yeah, I think that a pathspec "a/b" will not match "dir/a/b", because pathspecs are implicitly anchored to the start of the path. So "foo" in .gitignore will match "some/dir/foo". You'd need to "/foo" to anchor it to the top-level. But pathspecs always start at the top-level, and you'd need "**/foo" to be the equivalent of gitignore's "foo".

But even that's not entirely true. We allow "*" to match even directory separators in pathspecs (which is what makes "*.c" match anywhere), so "*/foo" is enough.

> But this is a bit of a tangent, and the pathspec entry is already, uh,
> complicated [1]. Without a good place to leave extra notes for cases
> like this, I'm not sure what to do. Certainly unifying the behavior
> would be incompatible (if obscure).

It's definitely complicated, but I'm not sure which of those features are important for command-line ergonomics, and which are just pointless inconsistencies. I'd be scared to start changing things and finding out. :)

I certainly don't have any objection to improving the pathspec documentation if it's unclear, though I think that can be done separately on top of the patch in this thread (and I'm not planning to tackle it myself).

-Peff
Previous: D. Ben KnobleNext: Ben Knoble
Message 19 of 20 in “Probable issue with code/documentation”
  1. Sruteesh KumarOct 10, 2025
  2. match_pathname(): give fnmatch one char of prefix contextJeff King, Oct 14, 2025
  3. Jeff KingOct 14, 2025
  4. Sruteesh KumarOct 22, 2025
  5. Junio C HamanoOct 23, 2025
  6. Sruteesh KumarOct 24, 2025
  7. Jeff KingOct 26, 2025
  8. Jeff KingOct 26, 2025
  9. 0/2 fix "foo**/bar" matching "foobar"Jeff King, Oct 26, 2025
  10. 1/2 match_pathname(): reorder prefix-match checkJeff King, Oct 26, 2025
  11. 2/2 match_pathname(): give fnmatch one char of prefix contextJeff King, Oct 26, 2025
  12. Junio C HamanoOct 26, 2025
  13. Jeff KingOct 27, 2025
  14. Junio C HamanoOct 27, 2025
  15. Jeff KingOct 28, 2025
  16. doc: document backslash in gitignore patternsJeff King, Oct 29, 2025
  17. Jeff KingOct 29, 2025
  18. D. Ben KnobleOct 30, 2025
  19. Jeff KingOct 30, 2025
  20. Ben KnobleOct 30, 2025

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.