3

I already tried many combinations of the .gitignore but none worked for what I need. I have this tree:

jobs/
jobs/projecta/config.xml
jobs/projecta/garbage
jobs/projecta/more/garbage
jobs/projectb/config.xml
jobs/projectb/garbage
jobs/projectb/more/garbage

Garbage means any other file. I want to commit only the config.xml files, and ignore everything inside jobs/ except them. So I tried:

/jobs/*
!/jobs/*/config.xml

This way, everything inside jobs are ignored, including the config.xml file. With the inverse order, same happens. So, I can force add all config files and changes to them will be tracked, but if I add a new folder inside jobs, it's config.xml won't appear as a untracked file, so this way people can forgot to add them.

I already tried with **, but I got the same.

Any ideas? Thanks!

Rafael Kassner
  • 1,123
  • 6
  • 21

1 Answers1

4

The question I mentioned in the comments actually answers this scenario; the crucial part is the following:

If a directory is excluded, Git will never look at the contents of that directory.

Which is just a rephrasing of this snippet from the gitignore documentation, emphasis mine.

It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.


Your pattern /jobs/* will ignore each file and folder in jobs. This means that git won't even look in this ignored folders to see if your !/jobs/*/config.xml pattern matches a file in them.

In turn you have to explicitly unignore the subfolders and then reignore the contents; after this you can again unignore your config.xml files. This might seem silly but that's how git handles ignores.

# Ignore everything in /jobs
/jobs/*
# Reinclude all folders in /jobs
!/jobs/*/
# Ignore everything in the subfolders of /jobs
/jobs/*/*
# Reinclude config.xml files in the first-level subfolders of /jobs
!/jobs/*/config.xml

This patterns will ignore everything but config.xml files in the first-level subfolders of jobs.

Community
  • 1
  • 1
Sascha Wolf
  • 18,810
  • 4
  • 51
  • 73
  • I understood the concept and in theory your example is right, but it does not work: https://gist.github.com/kassner/27f9ae2013928ee2d381 Something related to git version? I'm using `git version 1.9.3 (Apple Git-50)` – Rafael Kassner Mar 12 '15 at 17:23
  • 1
    @RafaelKassner Sorry, I forgot to mention that you should avoid copying the comments and trailing whitespaces. They mess with the gitignore. – Sascha Wolf Mar 12 '15 at 18:16
  • spaces really did made the difference is this case. It is fully working as I expected now. Thank you very much! – Rafael Kassner Mar 12 '15 at 18:43
  • I generally just put `!*/` at the end of `.gitignore` now and use `**` for trailing wildcards, list any directories I actually want to ignore after the `!*/`. `jobs/**!jobs/**/config.xml !*/`. – jthill Mar 12 '15 at 19:11