There are many questions on this topic, but none involve ~/.gitignore.
I have a strange project with a top-level project directory—call it project/—full of garbage, but with at least one important subdirectory—say project/feedme/. I'd like to .gitignore everything in project/, but un.gitignore project/feedme/ and its contents. This is easy with a negated pattern:
project$ cat .gitignore
/*
!/feedme/
I have a file project/feedme/.exrc which I would like to ignore. Being a vi user, I use .exrc files for local editor settings often, and so I have an entry in my ~/.gitconfig (specified by the core.excludesFile Git setting):
project$ cat ~/.gitignore
.exrc
Unfortunately git seems not to want to reignore .exrc:
project$ git status -s
?? feedme/
project$ git add feedme/
project$ git status -s
A feedme/.exrc
Why does Git not ignore project/feedme/.exrc?
Edit: This section is wrong, as per prosoitos' answer. See my edits at the end of this question, as it has not been completely answered.
Why do I think this should work? The manual page gitignore(5) says so:
Each line in a gitignore file specifies a pattern. When deciding whether to ignore a path, Git normally checks gitignore patterns from multiple sources, with the following order of precedence, from highest to lowest (within one level of precedence, the last matching pattern decides the outcome):
[…]
Patterns read from a .gitignore file in the same directory as the path, or in any parent directory, with patterns in the higher level files (up to the toplevel of the work tree) being overridden by those in lower level files down to the directory containing the
file. […][…]
Patterns read from the file specified by the configuration variable core.excludesFile.
Since patterns from ~/.gitignore are read last, I would have thought that the .exrc would be ignored in the end regardless of local .gitgnores.
A possible explanation is that this (again from the gitignore(5) manual page, emphasis mine)
It is not possible to re-include a file if a parent directory of that file is excluded.
also applies in its dual form (not in the manual page)
It is not possible to exclude a file if a parent directory of that file is re-included.
I would consider this a bug however if this is the case; at least it should be stated clearly in the documentation.
P.S.: My ~/.gitignore works under normal circumstances, so the problem is not there.
Edits
Prosoitos is right, the global ~/.gitignore is read first, so the project/feedme/ subdirectory is re-included after .exrcs are globally ignored. However I still face another oddity.
As I understand the documentation now, putting .exrc on the last line of my ~/.gitignore is equivalent (if project/.git/info/excludes is empty) to putting .exrc on the first line of project/.gitignore. Yet if I do this, project/feedme/.exrc is ignored this time!
project$ cat ~/.gitignore
project$ cat .gitignore
.exrc
/*
!/feedme/
project$ git ls-files --other --ignored --exclude-standard
.gitignore
feedme/.exrc
What is happening here?