Problem with gitignore file, if directory name contains dot character

the gitignore file does not exclude the marked directory, because it contains dots in its name: ‘V1.0.0’. Is there any resolution for this problem?

gitignore file:

#exclude everything from version control 
*.*

#add desired directories to version control  
!a-V*/**

directory list: (every directory includes a simple text file)

a-V1.0.0   (<-- notice the dots)
a-V2-0-0
a-V3-0-0
b-V1-0-0
b-V2-0-0

output from git status: (file a1.txt in a-V1.0.0 is missing)

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)  
	new file:   a-V2-0-0/a2.txt  
	new file:   a-V3-0-0/a3.txt

The reason isn’t because of the presence of the dot character (many filenames have dots too, either before the extension or at the beginning of the filename). From Git documentation:

An asterisk " * " matches anything except a slash.

so the kleen-star also matches dots in filenames.

#add desired directories to version control  
!a-V*/**

The above is better described as an exception rule, it doesn’t add anything, it just prevents the previous *.* from excluding files that match the negated pattern.

You need to check the current status of your files and folders to see what is being tracked and what is being ignored — .gitignore rules are not retroactive, so they will have no effect on files which are already being tracked. To verify the current status of ignored files in your repository type the following in the Bash terminal:

git ls-files -o -i --exclude-standard

The above is a useful command to try and figure out where and why .gitignore rules are not working as expected.

The above status message seems to confirm that your .gitignore exclusion rules are working as expected. If it’s working for the a-V2-0-0/ and a-V3-0-0/ folders there’s no reason it shouldn’t be also working for a-V1-0-0/. The fact that the a-V1-0-0/a1.txt is not being mentioned must be due to some other reason unrelated to the Git ignore rules — either the file was already committed and it’s not seen as changed, or some other explanation.

there’s no reason it shouldn’t be also working for a-V1-0-0/

If I rename the directory to a-V1-0-0/ everything works fine and all expected files are under version control. The problem is: For all pathnames, which includes dots e.g. a-V1.0.0/ my gitignore does not works as expected and files in those directories are not under version control.

I neead a solution (modification of my gitignore) which first ignores all content and after that exclude a few defined directories and all the files inside.

For some reasons, I don’t know why, this works perfectly with my gitignore listed above, if the pathnames did not include dots, but struggles with pathnames e.g. a-V1.0.0/

Sorry, my fault, I didn’t notice the difference between dots and hyphens in the names (poor eyesight and small fonts on the screen).

Mhhh, that’s strange anyhow; probably there’s a problem with the pattern definition then. I think that the first rule *.* is also matching folder names with dots in them in this case, and that the negation !a-V*/** might not be working out as expected because of the double **.

Try changing the .gitignore rule to (or add to it):

!/a-V*/*.*

Maybe this could work. Keep in mind that the exception rule that you wrote did not specify the root folder in the pattern, which is often the cause of rules ending up being applied where they weren’t intended to. When you want to apply a rule to specific folder, add the root / at the start, so you’re sure they’ll be applied to the root folders.

Did you try the suggested git ls-files .... command? It provides useful info on how Git is treating the ignore rules in the repository. In real practice, with projects containing lots of files, you’ll have to try and make both generic patterns and path-specific patterns, and the git ls-files …` command is going to be your best friend to check that everything is working as expected.

Try changing the .gitignore rule to (or add to it):

!/a-V*/*.*

This didn’t change the result. The files inside V1.0.0 stay not excluded, and as result will not be tracked.

The git list output shows as expected the ignored files:

PS D:\temp> git ls-files -o -i --exclude-standard 
.gitignore
a-V1.0.0/a1.txt
b-V1-0-0/b1.txt
b-V2-0-0/b2.txt

The problem, that a-V1.0.0/a1.txt is not tracked, will be confirmed.

It also doesn’t work correctly, if I explicit define the path to exclude from ignore list:

#exclude everything from version control 
*.*

#add desired directories to version control  
!a-V1.0.0/*
!a-V2-0-0/*
!a-V3-0-0/*

The result is again:

PS D:\temp> git status 
On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   a-V2-0-0/a2.txt
        new file:   a-V3-0-0/a3.txt

and file a-V1.0.0/a1.txt is again missing. Why ???

I’m really desperate.

Ok, I’ve created a temporary repository locally and played around with these patterns and some sample files.

From what I understood the problem could be that Git won’t see the file in the a-V1.0.0 folder until you add the folder to the work stage. The same goes for the other folders without the dots — until you git add the folder the file won’t be listed. This is what I got locally. Also, make sure that you’ve added the .gitignore file every time you change it.

If you’re just testing locally, you could delete the whole .git folder, and then run git init again, just to make sure you’re testing your patterns in a clean environment. Your ignore patterns were correct from the start (all the patterns suggested here were), the problem seems to be with the staging process.

And I confirm, the dot in the files and folders name is not the issue (the * matches them).

Thanks for your efforts. I tested and tried the above sample for many hours, but still can’t get it running as desired.

that Git won’t see the file in the a-V1.0.0 folder until you add the folder to the work stage

By using this

#exclude everything from version control 
*.*

#add desired directories to version control  
!a-V1.0.0/*
!a-V2-0-0/*
!a-V3-0-0/*

I can add / remove all desired folders from tracking just by activate / deactivate the lines containing the pathnames. The changings will be visible using git status, but this works only if the pathname does not include dots.

Did you successful try a similar example?
How does your gitignore looks like?

Hurray!! Finally I found the correct gitignore configuration:

#exclude everything from version control 
*/*

#add desired directories to version control  
!a-V1.0.0/*
!a-V2-0-0/*
!a-V3-0-0/*

Thanks for your help!

So it was just the pattern? Nothing to do with adding folders first?

It still puzzles my mind, because in my local tests I’ve reproduced the same folders and files structure, and the original patterns worked fine, but only after adding to the stage the folders (that’s on Win 10 Git Bash, so there might be some OS specific differences at play).

The important thing is that you solved your issue!