Very simply I wish to unignore a sub-directory in an ignored directory.
My .gitignore
:
app/migrations/
!app/migrations/config/Migrations/*
It does not work, if I remove the first line app/migrations
is unignored, but the 2nd line is not working as expected. I have also tried:
!app/migrations/config/*
But it seems it is not possible to un-ignore?
UPDATE
It would appear to be a short-coming of GIT which does not not correctly support un-ignoring sub-directories. Surprising that such a standard tool is unable to support such a simple configuration whether it be an oversight or a bug.
This will work, and from the root .gitignore
is the shortest sequence that will work efficiently:
app/migrations/*
!app/migrations/config
app/migrations/config/*
!app/migrations/config/Migrations
(It might be clearer and more explicit to write the second line as !app/migrations/config/
but as long as config
is a directory, the effect is the same. See my additional remarks below.)
In short you have to ignore then un-ignore each sub-directory.
That's correct, because when a directory is in fact ignored (by the last matching .gitignore
rule), this gives Git permission to omit scanning the directory entirely. As a result it never sees any of the files or sub-directories within that directory. It is, however, very efficient: Git never needs to open the directory in the first place! That's why this rule works the way it works.
However this does not work 100% since app/migrations/config/* is un-ignored when it should only be app/migrations/config/Migrations.
That's because you said to do that. Say to do what you mean, and you're OK. :-)
What's more this is not only over-complicated but also makes for an almost unreadable and bloated git-ignore file - 6 lines just to un-ignore a sub-sub-directory.
Well, four lines. That said, I do agree that this is overly complicated. Git should recognize the pattern:
dir/*
!dir/sub/something
and automatically insert the appropriate !dir/sub/
. Likewise for:
dir/*
!dir/sub1/sub2/something
Here, Git could automatically insert the !dir/sub1/
and !dir/sub1/sub2/
rules as needed, with corresponding "ignore all files within" rules as needed. These un-ignore insertions should end with /
in case dir/sub
, dir/sub1
, and/or dir/sub1/sub2
are files rather than directories.