I'm trying to solve a gitignore problem on a large directory structure, but to simplify my question I have reduced it to the following.
I have the following directory structure of two files (foo, bar) in a brand new git repository (no commits so far):
a/b/c/foo
a/b/c/bar
Obviously, a git status -u
shows:
# Untracked files:
...
# a/b/c/bar
# a/b/c/foo
What I want to do is create a .gitignore
file that ignores everything inside a/b/c but does not ignore the file foo
.
If I create a .gitignore
thus:
c/
Then a git status -u
shows both foo
and bar
as ignored:
# Untracked files:
...
# .gitignore
Which is as I expect.
Now if I add an exclusion rule for foo
, thus:
c/
!foo
According to the gitignore manpage, I'd expect this to to work. But it doesn't - it still ignores foo
:
# Untracked files:
...
# .gitignore
This doesn't work either:
c/
!a/b/c/foo
Neither does this:
c/*
!foo
Gives:
# Untracked files:
...
# .gitignore
# a/b/c/bar
# a/b/c/foo
In that case, although foo
is no longer ignored, bar
is also not ignored.
The order of the rules in .gitignore
doesn't seem to matter either.
This also doesn't do what I'd expect:
a/b/c/
!a/b/c/foo
That one ignores both foo
and bar
.
One situation that does work is if I create the file a/b/c/.gitignore and put in there:
*
!foo
But the problem with this is that eventually there will be other subdirectories under a/b/c
and I don't want to have to put a separate .gitignore
into every single one - I was hoping to create project-based .gitignore
files that can sit in the top directory of each project, and cover all the "standard" subdirectory structure.
This also seems to be equivalent:
a/b/c/*
!a/b/c/foo
This might be the closest thing to "working" that I can achieve, but the full relative paths and explicit exceptions need to be stated, which is going to be a pain if I have a lot of files of name foo
in different levels of the subdirectory tree.
Anyway, either I don't quite understand how exclusion rules work, or they don't work at all when directories (rather than wildcards) are ignored - by a rule ending in a /
.
Can anyone please shed some light on this?
Is there a way to make gitignore use something sensible like regular expressions instead of this clumsy shell-based syntax?
I'm using and observe this with git-1.6.6.1 on Cygwin/bash3 and git-1.7.1 on Ubuntu/bash3.