ripgrep: ./.gitignore: line 2: invalid use of **; must be one path component

**/something is valid .gitignore syntax, but rg prints an error

A leading “**” followed by a slash means match in all directories. For example, “**/foo” matches file or directory “foo” anywhere, the same as pattern “foo”. “**/foo/bar” matches file or directory “bar” anywhere that is directly under directory “foo”. (https://git-scm.com/docs/gitignore)

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 24 (13 by maintainers)

Commits related to this issue

Most upvoted comments

I’m going to close this because the current behavior is the conservative choice, and being conservative allows us to be flexible in the future. In particular, I think there is either a specification bug or an implementation bug in git, and I don’t know which one it is.

This is now fixed for good on master. ripgrep recognizes previously invalid ** patterns as two consecutive * patterns, in line with git’s updated spec.

Current master has a --no-ignore-messages that will suppress just these types of error messages. It will be in the next release.

Had the same issue, I always thought git used fnmatch for this. I looked through git and see that actually moved to use wildmatch (https://github.com/davvid/wildmatch) in recent versions. Without looking too much into it I think this may be the reason for it.

The wildmatch extension allows ** to match / when WM_PATHNAME is present. This gives the practical benefit of being able to match all subdirectories of a path by using ** and reserves the use of the single-asterisk * character for matching within path components.

I have sent an email to the Git mailing list requesting that the **.extension format be added to the documentation of Git ignore.

It already has been. See the commit referenced in #1098

@BurntSushi imho it might be worth choosing consistency with implementation over spec in this case and making a prominent note of it

It looks like *literal will be matched prior to a call to wildmatch. If it’s **literal, it will be passed to wildmatch, where the first and second wildcards will be consumed, the WM_PATHNAME flag will not have been set, the rest of theliteral text consumed, and a successful match will be returned.

Side note, wildmatch was integrated in v1.8.2-rc0 and a prior tag (v1.8.1.6) reproduces the behavior of git to match **.txt to hello.txt so it seems it wasn’t a bug introduced when wildmatch was integrated.

Looks like the spec and implementation are just inconsistent…?