忽略 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:19:45  来源:igfitidea点击:

Unignore subdirectories of ignored directories in Git

gitgitignore

提问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_MEdirectory. 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:

根据gitignore 文档的模式格式部分

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 LinJohn的回答很有帮助,但我需要将两者结合起来。

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 .gitignoreabove, then all the intermediate files would have been included as well, so for example uploads/rubbish/awould show up in the status command above.

如果我们uploads/*.gitignore上面使用过,那么所有中间文件也将被包含在内,因此例如uploads/rubbish/a将显示在上面的状态命令中。