Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are multiple `.gitignore`s frowned on?

Tags:

git

People also ask

Is it OK to have multiple Gitignore files?

A . gitignore file is a plain text file where each line contains a pattern for files/directories to ignore. Generally, this is placed in the root folder of the repository, and that's what I recommend. However, you can put it in any folder in the repository and you can also have multiple .

Does order of Gitignore matter?

The order of the rules in . gitignore doesn't seem to matter either.

Should .gitignore be ignored?

The . gitignore file's purpose is to prevent everyone who collaborates on a project from accidentally commiting some common files in a project, such as generated cache files. Therefore you should not ignore .

Does Gitignore get cloned?

The process of cloning ignores the . gitignore file. If a file is added, committed and another commit with the . gitignore is created, the file will still be part of the repository and therefore cloned.


I can think of at least two situations where you would want to have multiple .gitignore files in different (sub)directories.

  • Different directories have different types of file to ignore. For example the .gitignore in the top directory of your project ignores generated programs, while Documentation/.gitignore ignores generated documentation.

  • Ignore given files only in given (sub)directory (you can use /sub/foo in .gitignore, though).

Please remember that patterns in .gitignore file apply recursively to the (sub)directory the file is in and all its subdirectories, unless pattern contains '/' (so e.g. pattern name applies to any file named name in given directory and all its subdirectories, while /name applies to file with this name only in given directory).


As a tangential note, one case where the ability to have multiple .gitignore files is very useful is if you want an extra directory in your working copy that you never intend to commit. Just put a 1-byte .gitignore (containing just a single asterisk) in that directory and it will never show up in git status etc.


You can have multiple .gitignore, each one of course in its own directory.
To check which gitignore rule is responsible for ignoring a file, use git check-ignore: git check-ignore -v -- afile.

And you can have different version of a .gitignore file per branch: I have already seen that kind of configuration for ensuring one branch ignores a file while the other branch does not: see this question for instance.

If your repo includes several independent projects, it would be best to reference them as submodules though.
That would be the actual best practices, allowing each of those projects to be cloned independently (with their respective .gitignore files), while being referenced by a specific revision in a global parent project.
See true nature of submodules for more.


Note that, since git 1.8.2 (March 2013) you can do a git check-ignore -v -- yourfile in order to see which gitignore run (from which .gitignore file) is applied to 'yourfile', and better understand why said file is ignored.
See "which gitignore rule is ignoring my file?"


Pro single

  • Easy to find.

  • Hunting down exclusion rules can be quite difficult if I have multiple gitignore, at several levels in the repo.

  • With multiple files, you also typically wind up with a fair bit of duplication.

Pro multiple

  • Scopes "knowledge" to the part of the file tree where it is needed.

  • Since Git only tracks files, an empty .gitignore is the only way to commit an "empty" directory.

    (And before Git 1.8, the only way to exclude a pattern like my/**.example was to create my/.gitignore in with the pattern **.foo. This reason doesn't apply now, as you can do /my/**/*.example.)


I much prefer a single file, where I can find all the exclusions. I've never missed per-directory .svn, and I won't miss per-directory .gitignore either.

That said, multiple gitignores are quite common. If you do use them, at least be consistent in their use to make them reasonable to work with. For example, you may put them in directories only one level from the root.


There are many scenarios where you want to commit a directory to your Git repo but without the files in it, for example the logs, cache, uploads directories etc.

So what I always do is to add a .gitignore file in those directories with the following content:

# this directory is intentionally ignored
/*
!/.gitignore

With this .gitignore file, Git will not track any files in those directories yet still allow me to add the .gitignore file and hence the directory itself to the repo.