忽略 Git 中被忽略目录的子目录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5261959/
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
Unignore subdirectories of ignored directories in Git
提问by Wil
Let's say I have ignored a directory, but I want to unignore specific subdirectories therein. So I have the setup:
假设我忽略了一个目录,但我想忽略其中的特定子目录。所以我有设置:
/uploads/
/uploads/rubbish/
/uploads/rubbish/stuff/KEEP_ME/
/uploads/foo/
/uploads/foo/bar/lose/
And I want to ignore everything but the KEEP_ME
directory. I would hope the ignore would look something like:
我想忽略除KEEP_ME
目录之外的所有内容。我希望忽略看起来像:
/uploads/*
!/uploads/rubbish/stuff/KEEP_ME/
But that's not working, and neither are several permutations on the same theme.
但这不起作用,同一主题的几种排列也不起作用。
One that does work is
一个有效的方法是
/uploads/**/**/**/
!/uploads/rubbish/stuff/KEEP_ME/
But that feels a little restrictive and verbose?
但这感觉有点限制和冗长?
回答by Art Shayderov
According to pattern format section of the gitignore documentation:
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. 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".
一个可选的前缀“!” 这否定了模式;任何被先前模式排除的匹配文件将再次包含在内。如果排除了该文件的父目录,则无法重新包含该文件。出于性能原因,Git 不会列出排除的目录,因此包含文件的任何模式都不起作用,无论它们在哪里定义。在第一个“!”前面放一个反斜杠(“\”)对于以文字“!”开头的模式,例如,“!important!.txt”。
Therefore the previously-excluded parent directory /uploads/rubbish/stuff/keep/
pattern must be exclusively negated before negating its content:
因此,/uploads/rubbish/stuff/keep/
在否定其内容之前,必须专门否定先前排除的父目录模式:
#ignore everything within /uploads/
/uploads/*
#include everything within /uploads/rubbish/stuff/keep
!/uploads/rubbish/stuff/keep/
!/uploads/rubbish/stuff/keep/*
To include subdirectories inside /uploads/rubbish/stuff/keep/
add the third line:
要在其中包含子目录,请/uploads/rubbish/stuff/keep/
添加第三行:
!/uploads/rubbish/stuff/keep/**/*
回答by KingCrunch
Even if you add something to .gitignore
, you can forcegit to add it to the index
即使你添加了一些东西.gitignore
,你也可以强制git 将它添加到索引中
git add --force uploads/rubbish/stuff/KEEP_ME/
However, "KEEP_ME" seems to be a directory and git usually doesnt like empty folder, so you should can add a "placeholder"-holder file instead, if the folder is empty
然而,“KEEP_ME”似乎是一个目录,git通常不喜欢空文件夹,所以你应该添加一个“占位符”-holder文件,如果文件夹是空的
git add --force uploads/rubbish/stuff/KEEP_ME/.keep_me
回答by John
Was trying to figure out how to include a specific folder when excluding all folders with the generic exclusion
在排除具有通用排除项的所有文件夹时,试图弄清楚如何包含特定文件夹
**/build
if you add the /*
to the end of your generic exclude you continue to exclude all build files **/build/*
如果您将/*
加到通用排除的末尾,您将继续排除所有构建文件**/build/*
Then you add another line to correct for the path that you want to be included to look like
然后添加另一行以更正要包含的路径,使其看起来像
!**/folder/build/*
leaving us a gitignore that reads
给我们留下了一个 gitignore,上面写着
**/build/*
!**/folder/build/*
回答by JosiahYoder-deactive except..
Buo-Ren Linand John's answers are quite helpful, but I needed to combine both.
Buo-Ren Lin和John的回答很有帮助,但我需要将两者结合起来。
When wanting to exclude other sub-folders as well as files within uploads, I found it necessary to explicitly specify arbitrary directories before the given folder both while excluding the folder and while including the sub-folder
当想要排除其他子文件夹以及上传中的文件时,我发现有必要在给定文件夹之前明确指定任意目录,同时排除文件夹和包含子文件夹
**/uploads/*
!**/uploads/rubbish/
!**/uploads/rubbish/*
I also found it necessary to explicitly re-include both the sub-folder and its contents to show both items within the folder and sub-folders.
我还发现有必要明确重新包含子文件夹及其内容以显示文件夹和子文件夹中的两个项目。
回答by user295691
The solution presented as the most-upvoted answer is incorrect, and easily demonstrable as such.
作为最高投票答案提出的解决方案是不正确的,因此很容易证明。
Start with ignoring everything in uploads/*:
首先忽略uploads/* 中的所有内容:
mkdir -p uploads/rubbish/stuff/KEEP_ME
touch uploads/a uploads/rubbish/a uploads/rubbish/stuff/a uploads/rubbish/stuff/KEEP_ME/a
echo '/uploads/*' >> .gitignore
git init
git add .
git commit -m "Initial commit"
Now unignore the parent directory of the ignored stuff as above:
现在取消忽略被忽略的东西的父目录,如上:
echo 'uploads/rubbish/stuff/KEEP_ME/' >> .gitignore
echo 'uploads/rubbish/stuff/KEEP_ME/*' >> .gitignore
git status -u
Shows no untracked files.
显示没有未跟踪的文件。
In order to get it to work, you need to ignore all files under the uploads/
tree (uploads/**/*
, not just the top level, uploads/*
) and then add all parent directories of the tree you want to keep
为了让它工作,您需要忽略uploads/
树下的所有文件(uploads/**/*
,而不仅仅是顶层,uploads/*
),然后添加要保留的树的所有父目录
echo '/uploads/**/*' > .gitignore
echo '!/uploads/rubbish/' >> .gitignore
echo '!/uploads/rubbish/stuff' >> .gitignore
echo '!/uploads/rubbish/stuff/KEEP_ME' >> .gitignore
echo '!/uploads/rubbish/stuff/KEEP_ME/*' >> .gitignore
git status -u
Which gives:
这使:
On branch master
...
Untracked files:
(use "git add <file>..." to include in what will be committed)
uploads/rubbish/stuff/KEEP_ME/a
If we had used uploads/*
in the .gitignore
above, then all the intermediate files would have been included as well, so for example uploads/rubbish/a
would show up in the status command above.
如果我们uploads/*
在.gitignore
上面使用过,那么所有中间文件也将被包含在内,因此例如uploads/rubbish/a
将显示在上面的状态命令中。