9

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?

roim
  • 4,780
  • 2
  • 27
  • 35
  • 3
    Use multiple lines: `*.so` `*.so.[0-9]` `*.so.[0-9].[0-9]` etc. If revs may go into two digits you'll need even more glob patterns. (hg has `syntax:` directives in its `.hgignore` so that you can mix regex and glob as desired; maybe someone will add something like this to git someday.) – torek Oct 15 '13 at 21:30
  • 1
    Just keeping separate install hierarchy solves this kind of thing entirely anyway. – jthill Jul 02 '14 at 01:43
  • Of interest: https://github.com/git/git/commit/2e22a85e5c01d041434682fe75f58be94de0801b – VonC Feb 18 '18 at 19:23

5 Answers5

13

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
Community
  • 1
  • 1
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • This is not *exactly* the same (although it's probably just fine): for instance, it matches `a.so.` and `b.so...9`. – torek Jul 04 '14 at 16:51
  • Yes, I am not an expert so I don't know who should I trust most, but I feel like @torek answer is safer and clear. Tell me if I am wrong. – arthur.sw Jul 05 '14 at 09:52
  • 1
    @mu無 Everything that will be match by `*.so.[0-9]*.[0-9]*` will also be match by `*.so.[0-9]*`, right? How to write `*.so.someDigits.someDigits`, `someDigits` being only `any number of digits`? – arthur.sw Jul 05 '14 at 15:13
  • @arthur.sw If you want to write `*.so.someDigits.someDigits`, `someDigits` being `any number of digits` in a single line, you will need to use pattern `*.so[.0-9]*` as I suggested earlier, which will ignore all these. But it will also ignore files of the type `*.so...`, though they won't be generated under normal flow. – Anshul Goyal Jul 05 '14 at 15:17
  • 1
    @mu無 I think your pattern will match `my.pattern.is.so.6ood`. I agree it is not a big deal. – arthur.sw Jul 06 '14 at 12:28
  • @mu無 I will give you the bounty if you correct your answer: `*.so.[0-9]*.[0-9]*` and `*.so.[0-9]*.[0-9]*.[0-9]*` are useless since it is already taken into account in `.so.[0-9]*`. This means that you should change your edit. And it would be better if the solution appears first: only those two lines `*.so` and `*.so.[0-9]*`. – arthur.sw Jul 07 '14 at 14:11
  • arthur.sw Check the edits - I have made the changes. – Anshul Goyal Jul 08 '14 at 06:18
  • Not really an answer, but apparently there's no answer, so I'll have to pick yours – roim Apr 12 '15 at 03:43
5

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

SpeakEasyV
  • 59
  • 2
  • 2
    I wanted better control just to be safe. I'm always "discovering" new extensions. – roim Oct 15 '13 at 22:05
1

I think you can accomplish it in two lines:

.so
.so.[0-9]*
infused
  • 24,000
  • 13
  • 68
  • 78
0

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...

Community
  • 1
  • 1
arthur.sw
  • 11,052
  • 9
  • 47
  • 104
0

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.

FaiChou
  • 767
  • 7
  • 16