.gitignore exclude folder but include specific sub

2018-12-31 01:24发布

I have the folder application/ which I add to the .gitignore. Inside the application/ folder is the folder application/language/gr. How can I include this folder? I've tried this

application/
!application/language/gr/

with no luck...

标签: git gitignore
14条回答
墨雨无痕
2楼-- · 2018-12-31 01:55

If you exclude application/, then everything under it will always be excluded (even if some later negative exclusion pattern (“unignore”) might match something under application/).

To do what you want, you have to “unignore” every parent directory of anything that you want to “unignore”. Usually you end up writing rules for this situation in pairs: ignore everything in a directory, but not some certain subdirectory.

# you can skip this first one if it is not already excluded by prior patterns
!application/

application/*
!application/language/

application/language/*
!application/language/gr/

Note
The trailing /* is significant:

  • The pattern dir/ excludes a directory named dir and (implicitly) everything under it.
    With dir/, Git will never look at anything under dir, and thus will never apply any of the “un-exclude” patterns to anything under dir.
  • The pattern dir/* says nothing about dir itself; it just excludes everything under dir. With dir/*, Git will process the direct contents of dir, giving other patterns a chance to “un-exclude” some bit of the content (!dir/sub/).
查看更多
宁负流年不负卿
3楼-- · 2018-12-31 01:55

I have found a similar case here, where in laravel by default, .gitignore ignores all using asterix, then overrides the public directory.

*
!public
!.gitignore

This is not sufficient if you run into the OP scenario.

If you want to commit a specific subfolders of public, say for e.g. in your public/products directory you want to include files that are one subfolder deep e.g. to include public/products/a/b.jpg they wont be detected correctly, even if you add them specifically like this !/public/products, !public/products/*, etc..

The solution is to make sure you add an entry for every path level like this to override them all.

*
!.gitignore
!public/
!public/*/
!public/products/
!public/products/*
!public/products/*/
!public/products/*/
!public/products/*/*
查看更多
倾城一夜雪
4楼-- · 2018-12-31 01:58

In WordPress, this helped me:

wp-admin/
wp-includes/
/wp-content/*
!wp-content/plugins/
/wp-content/plugins/*
!/wp-content/plugins/plugin-name/
!/wp-content/plugins/plugin-name/*.*
!/wp-content/plugins/plugin-name/**
查看更多
爱死公子算了
5楼-- · 2018-12-31 01:58

I wanted to track jquery production js files and this worked:

node_modules/*
!node_modules/jquery
node_modules/jquery/*
!node_modules/jquery/dist/*
查看更多
不流泪的眼
6楼-- · 2018-12-31 01:58

gitignore - Specifies intentionally untracked files to ignore.

Example to exclude everything except a specific directory foo/bar (note the /* - without the slash, the wildcard would also exclude everything within foo/bar):

$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar

Another example for WordPress:

!/wp-content
wp-content/*
!/wp-content/plugins
wp-content/plugins/*
!wp-content/plugins/my-awesome-plugin

More informations in here: https://git-scm.com/docs/gitignore

查看更多
看淡一切
7楼-- · 2018-12-31 02:00

Commit 59856de from Karsten Blees (kblees) for Git 1.9/2.0 (Q1 2014) clarifies that case:

gitignore.txt: clarify recursive nature of excluded directories

An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again.

It is not possible to re-include a file if a parent directory of that file is excluded. (*)
(*: unless certain conditions are met in git 2.8+, see below)
Git doesn't list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.

Put a backslash ("\") in front of the first "!" for patterns that begin with a literal "!", for example, "\!important!.txt".

Example to exclude everything except a specific directory foo/bar (note the /* - without the slash, the wildcard would also exclude everything within foo/bar):

 --------------------------------------------------------------
     $ cat .gitignore
     # exclude everything except directory foo/bar
     /*
     !/foo
     /foo/*
     !/foo/bar
 --------------------------------------------------------------

In your case:

application/*
!application/**/
application/language/*
!application/language/**/
!application/language/gr/**

You must white-list folders first, before being able to white-list files within a given folder.


Update Feb/March 2016:

Note that with git 2.9.x/2.10 (mid 2016?), it might be possible to re-include a file if a parent directory of that file is excluded if there is no wildcard in the path re-included.

Nguyễn Thái Ngọc Duy (pclouds) is trying to add this feature:

So with git 2.9+, this could have actually worked, but was ultimately reverted:

application/
!application/language/gr/
查看更多
登录 后发表回答