git .gitignore 排除文件夹但包含特定的子文件夹
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5533050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
.gitignore exclude folder but include specific subfolder
提问by chchrist
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?
我有application/
我添加到.gitignore
. application/
文件夹里面是 文件夹application/language/gr
。如何包含此文件夹?
I've tried this
我试过这个
application/
!application/language/gr/
with no luck...
没有运气...
回答by Chris Johnsen
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/
).
如果您 exclude application/
,则它下面的所有内容都将始终被排除(即使稍后的某些否定排除模式(“unignore”)可能与 下的某些内容匹配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 nameddir
and (implicitly) everything under it.
Withdir/
, Git will never look at anything underdir
, and thus will never apply any of the “un-exclude” patterns to anything underdir
. - The pattern
dir/*
says nothing aboutdir
itself; it just excludes everything underdir
. Withdir/*
, Git will process the direct contents ofdir
, giving other patterns a chance to “un-exclude” some bit of the content (!dir/sub/
).
- 该模式
dir/
排除了一个名为的目录dir
及其下的(隐式)所有内容。
随着dir/
,Git会从来不看任何事情下dir
,因而绝不会任意的“非排除”模式应用于下的任何dir
。 - 该模式
dir/*
没有说明dir
它本身;它只是排除了dir
. 使用dir/*
,Git 将处理 的直接内容dir
,让其他模式有机会“取消排除”某些内容 (!dir/sub/
)。
回答by VonC
Commit 59856defrom Karsten Blees (kblees)for Git 1.9/2.0 (Q1 2014) clarifies that case:
来自Karsten Blees (kblees)for Git 1.9/2.0 (Q1 2014) 的Commit 59856de阐明了这种情况:
gitignore.txt
: clarify recursive nature of excluded directories
gitignore.txt
:澄清排除目录的递归性质
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 withinfoo/bar
):
一个可选的前缀“
!
”,它否定了模式;任何被先前模式排除的匹配文件将再次包含在内。如果排除了该文件的父目录,则无法重新包含该文件。(
*
)
(*
: 除非在 git 2.8+ 中满足某些条件,请参见下文)
Git 不会出于性能原因列出排除的目录,因此包含文件的任何模式都无效,无论它们在哪里定义。对于以文字“ ”开头的模式,例如“ ”,
\
在第一个“!
”之前放置一个反斜杠(“ ”)。!
\!important!.txt
排除除特定目录之外的所有内容的示例
foo/bar
(注意/*
- 没有斜杠,通配符也会排除 中的所有内容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 foldersfirst, before being able to white-list files within a given folder.
您必须先将文件夹列入白名单,然后才能将给定文件夹中的文件列入白名单。
Update Feb/March 2016:
2016 年 2 月/3 月更新:
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.
请注意,对于 git 2.9.x/2.10(2016 年中期?),如果路径 re-included 中没有通配符,则如果排除该文件的父目录,则可能会重新包含该文件。
Nguy?n Thái Ng?c Duy (pclouds
)is trying to add this feature:
Nguy?n Thái Ng?c Duy ( pclouds
)正在尝试添加此功能:
- commit 506d8f1for git v2.7.0, reverted in commit 76b620dgit v2.8.0-rc0
- commit 5e57f9cgit v2.8.0-rc0,... reverted(!) in commit 5cee3493git 2.8.0.
- 为 git v2.7.0提交 506d8f1,在提交 76b620dgit v2.8.0-rc0 中恢复
- 提交 5e57f9cgit v2.8.0-rc0,...在提交 5cee3493git 2.8.0 中恢复(!)。
So with git 2.9+, this could have actually worked, but was ultimately reverted:
所以对于 git 2.9+,这实际上可以工作,但最终被恢复:
application/
!application/language/gr/
回答by rpyzh
@Chris Johnsen's answer is great, but with a newer versions of Git (1.8.2 or later), there is a double asterisk pattern you can leverage for a bit more shorthand solution:
@Chris Johnsen 的回答很好,但是对于更新版本的 Git(1.8.2 或更高版本),您可以利用双星号模式来获得更多速记解决方案:
# assuming the root folder you want to ignore is 'application'
application/**/*
# the subfolder(s) you want to track:
!application/language/gr/
This way you don't have to "unignore" parent directory of the subfolder you want to track.
这样您就不必“忽略”要跟踪的子文件夹的父目录。
With Git 2.17.0 (Not sure how early before this version. Possibly back to 1.8.2), using the **
pattern combined with excludes for each subdirectory leading up to your file(s) works. For example:
使用 Git 2.17.0(不知道在这个版本之前多早。可能回到 1.8.2),使用**
模式结合排除导致你的文件的每个子目录工作。例如:
# assuming the root folder you want to ignore is 'application'
application/**
# Explicitly track certain content nested in the 'application' folder:
!application/language/
!application/language/gr/
!application/language/gr/** # Example adding all files & folder in the 'gr' folder
!application/language/gr/SomeFile.txt # Example adding specific file in the 'gr' folder
回答by Katie
There are a bunch of similar questions about this, so I'll post what I wrote before:
关于这个有一堆类似的问题,所以我会发布我之前写过的内容:
The only way I got this to work on my machine was to do it this way:
我让它在我的机器上工作的唯一方法是这样做:
# Ignore all directories, and all sub-directories, and it's contents:
*/*
#Now ignore all files in the current directory
#(This fails to ignore files without a ".", for example
#'file.txt' works, but
#'file' doesn't):
*.*
#Only Include these specific directories and subdirectories:
!wordpress/
!wordpress/*/
!wordpress/*/wp-content/
!wordpress/*/wp-content/themes/
!wordpress/*/wp-content/themes/*
!wordpress/*/wp-content/themes/*/*
!wordpress/*/wp-content/themes/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*/*
Notice how you have to explicitly allow content for each level you want to include. So if I have subdirectories 5 deep under themes, I still need to spell that out.
请注意您必须如何明确允许您想要包含的每个级别的内容。所以如果我在主题下面有 5 个子目录,我仍然需要把它拼出来。
This is from @Yarin's comment here: https://stackoverflow.com/a/5250314/1696153
这是来自@Yarin 的评论:https: //stackoverflow.com/a/5250314/1696153
These were useful topics:
这些是有用的主题:
I also tried
我也试过
*
*/*
**/**
and **/wp-content/themes/**
和 **/wp-content/themes/**
or /wp-content/themes/**/*
或者 /wp-content/themes/**/*
None of that worked for me, either. Lots of trial and error!
这些都不适合我。大量的试验和错误!
回答by Steve Kling
I've found only this actuallyworks.
我发现只有这个确实有效。
**/node_modules/*
!**/node_modules/keep-dir
回答by D. Ben Knoble
The simplest and probably best way is to try adding the files manually (generally this takes precedence over .gitignore
-style rules):
最简单也可能是最好的方法是尝试手动添加文件(通常这优先于.gitignore
-style 规则):
git add /path/to/module
You may even want the -N
intent to addflag, to suggest you willadd them, but not immediately. I often do this for new files I'm not ready to stage yet.
你甚至可以在-N
意图添加标志,建议您将它们添加,但不是马上。我经常为尚未准备好上演的新文件执行此操作。
This a copy of an answerposted on what could easily be a duplicate QA. I am reposting it here for increased visibility—I find it easier not to have a mess of gitignore rules.
这是发布在很容易成为重复 QA的答案的副本。我将它重新发布在这里是为了提高可见性——我发现不要把 gitignore 规则弄得一团糟更容易。
回答by Dongdong
Add an additional answer:
添加一个额外的答案:
!/.vs/ <== include this folder to source control, folder only, nothing else
/.vs/* <== but ignore all files and sub-folder inside this folder
!/.vs/ProjectSettings.json <== but include this file to source control
!/.vs/config/ <== then include this folder to source control, folder only, nothing else
!/.vs/config/* <== then include all files inside the folder
here is result:
这是结果:
回答by Abdennour TOUMI
So , since many programmers uses node . the use case which meets this question is to exclude node_modules
except one module module-a
for example:
因此,由于许多程序员使用 node 。满足这个问题的用例是排除node_modules
一个模块module-a
,例如:
!node_modules/
node_modules/*
!node_modules/module-a/
回答by Breit
Especially for the older Git versions, most of the suggestions won't work that well. If that's the case, I'd put a separate .gitignore in the directory where I want the content to be included regardless of other settings and allow there what is needed.
特别是对于较旧的 Git 版本,大多数建议都不会那么好用。如果是这种情况,我会将一个单独的 .gitignore 放在我希望包含内容的目录中,而不管其他设置如何,并允许需要的内容。
For example: /.gitignore
例如:/.gitignore
# ignore all .dll files
*.dll
/dependency_files/.gitignore
/dependency_files/.gitignore
# include everything
!*
So everything in /dependency_files (even .dll files) are included just fine.
所以 /dependency_files 中的所有内容(甚至 .dll 文件)都包含在内。
回答by blamb
I have found a similar case here, where in laravel by default, .gitignore
ignores all using asterix, then overrides the public directory.
我在这里发现了一个类似的情况,默认情况下在 laravel 中,.gitignore
忽略所有使用 asterix,然后覆盖公共目录。
*
!public
!.gitignore
This is not sufficient if you run into the OP scenario.
如果您遇到 OP 场景,这还不够。
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..
如果您要提交的特定子文件夹public
,譬如说例如,在你的public/products
目录要包括那些一个子文件夹深如文件,包括public/products/a/b.jpg
他们不会正确检测,即使你加他们特别喜欢这个!/public/products
,!public/products/*
等。
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/*/*