Search code examples
gitgitignoresubdirectory

Not able to un-ignore GIT sub-directory


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.


Solution

  • 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.