roim
roim

Reputation: 4930

Regex-like shell glob patterns for gitignore

When I compile my C++ project, many shared object files are created with extensions such as

.so
.so.0
.so.7
.so.0.7

I need to add all those to my .gitignore file. Were this a regex, I could use

\.so[\.0-9]*

However, the documentation says that .gitignore

treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_PATHNAME flag

I found no way to do what I want with the fnmatch documentations I found. Is there really no way to do this?

Upvotes: 9

Views: 5659

Answers (5)

FaiChou
FaiChou

Reputation: 867

Python has a module named fnmatch, you can use that to verify whether a particular filename matches the pattern or not.

Not exactly correct like @mu 無 said.

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

For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".

But I tried in fnmatch:

>>> p = "/*.c"
>>> f = "cat-file.c"
>>> fnmatch(f, p)
False
>>> f2 = "abc/def/cat-file.c"
>>> fnmatch(f2, p)
False
>>> p2 = "*.c"
>>> fnmatch(f, p2)
True
>>> fnmatch(f2, p2)
True

fnmatch not match cat-file.c but .gitignore support.

Upvotes: 0

Anshul Goyal
Anshul Goyal

Reputation: 76997

While the answer by @SpeakEasy can ignore .so files in a single step using *.so*, for your use case of ignoring files in formats specified, you can use two entries in your .gitignore for more specific ignore rule

*.so
*.so.[0-9]*

From gitignore man page

Each line in a gitignore file specifies a pattern.

Git treats the pattern as a shell glob suitable for consumption by fnmatch

The important thing to note is that the pattern is not the same as regular expressions.

Python has a module named fnmatch, you can use that to verify whether a particular filename matches the pattern or not.

Sample example:

import fnmatch
pattern = "*.so.[0-9]*"
filenames = ["a.so", "b.so.0", "b.so.11", "b.so.1.0", "b.so.1.0.12"]

for filename in filenames:
    print filename, fnmatch.fnmatch(filename, pattern)

>>> a.so False
    b.so.0 True
    b.so.11 True
    b.so.1.0 True
    b.so.1.0.12 True

Upvotes: 14

arthur.sw
arthur.sw

Reputation: 11639

From torek's comment:

Use multiple lines:

*.so
*.so.[0-9]
*.so.[0-9].[0-9]

etc.

I don't know if there is a better way...

Upvotes: 0

infused
infused

Reputation: 24337

I think you can accomplish it in two lines:

.so
.so.[0-9]*

Upvotes: 1

SpeakEasyV
SpeakEasyV

Reputation: 94

Does adding the line *.so* not work? Or do you need more fine control?

Upvotes: 5

Related Questions