Harry Solovay
Harry Solovay

Reputation: 513

Gitignore all non-matching a particular pattern

I've attempted to use the following in my .gitignore to no avail (files are being ignored, regardless of the !):

*
!(CODE_OF_CONDUCT|CONTRIBUTING|README).md
!.(editorconfig|github|gitignore|prettierrc|versionrc|vscode)
!(docs|example|LICENSE|src)
!(package|package-lock|(tsconfig.*)).json

Is there a way that I can get the above to work? That is, to match and exclude all except those that align with the described patterns.

Upvotes: 1

Views: 917

Answers (1)

buddemat
buddemat

Reputation: 5301

I believe .gitignore uses filename globs, not regular expressions (and afaik also not extended globbing). As a result, the parentheses, the 'pipe symbol' (|), etc. have no special meaning and are interpreted as part of the filenames.

Unfortunately, I don't think there is any way to express the or within the patterns. You need to do something along the lines of this (I did not include all original files):

*
!CODE_OF_CONDUCT.md
!CONTRIBUTING.md
!README.md
!.editorconfig
!.github
!.gitignore
!tsconfig.*.json

If applicable, you can maybe group some files by common name parts, e.g.

!.git*

or by their extension, like

!*.md

and/or restrict the pattern to uppercase filenames

![ABCDEFGHIJKLMNOPQRSTUVWXYZ]*.md

(Note that this is not the same as [A-Z]*, since standard glob sorts AaBbCc etc., so the latter means all upper- and lowercase characters except lowercase z).

You could also 'group' by sub-directories, but that does not seem applicable in your case.

See https://git-scm.com/docs/gitignore


Edit: an indirect way of doing what you want, is using a more compact syntax when you generate the file (credits to @jthill):

printf %s\\n \!{package,package-lock,tsconfig.*}.json >>.gitignore 

However, this will not make the resulting file shorter.

Upvotes: 1

Related Questions