简体   繁体   English

gitignore:忽略文件夹层次结构中的所有文件,除了一种特定的文件类型

[英]gitignore: Ignore all files in folder hierarchy except one specific filetype

I'd like to ignore all files below and in a folder except a specific filetype that could be somewhere in the folders hierarchy: 我想忽略文件夹中下方和文件夹中的所有文件,但可能位于文件夹层次结构中的特定文件类型除外:

Example

/Test
/Test/unknown/folder/structure/below

Now I'd like to ignore all files in and below the Test folder except a certain css file named layout.css , eg: 现在,我想忽略Test文件夹中及其下方的所有文件,除了某些名为layout.css CSS文件之外,例如:

/Test/layout.css
/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/layout.css
/Test/in/a/unknown/folder/ignore.me

.gitignore should ignore .gitignore应该忽略

/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/ignore.me

My .gitignore file does not work: 我的.gitignore文件不起作用:

Test/
!layout.css

Any suggestions? 有什么建议么?

I was able to get your example to work by putting a .gitignore file in the Test/ directory with the following contents. 通过将.gitignore文件放在Test/目录中,可以得到您的示例,其中包含以下内容。

*
!*/
!.gitignore
!layout.css

In order to accomplish what you want, you'll need to use some negative exclusions. 为了完成您想要的工作,您需要使用一些否定排除项。

The basic idea is that you need to exclude every parent directory of any file that you want unignored. 基本思想是您需要排除要忽略的任何文件的每个父目录。

So, if you want /Test/in/a/unknown/folder/layout.css to be added to your git repo, then you'll have to unignore /Test/, /Test/in/, /Test/in/a/, /Test/in/a/unknown/, and /Test/in/a/unknown/folder/. 因此,如果您希望将/Test/in/a/unknown/folder/layout.css添加到git仓库中,则必须忽略/ Test /,/ Test / in /,/ Test / in / a /,/ Test / in / a / unknown /和/ Test / in / a / unknown / folder /。

Then, when you finally get to the directory with some ignored and some unignored files, you'll need to specify each individually as follows: 然后,当您最终进入包含一些被忽略文件和一些未被忽略文件的目录时,需要分别指定每个文件,如下所示:

# Fille: .gitignore
!Test/
Test/*
!Test/layout.css
Test/fileto.ignore
!Test/another/
Test/another/*
!Test/another/folder/
Test/another/folder/*
!Test/in/
Test/in/*
!Test/in/a/
Test/in/a/*
!Test/in/a/unknown/
Test/in/a/unknown/*
!Test/in/a/unknown/folder/
Test/in/a/unknown/folder/ignore.me
!Test/in/a/unknown/folder/layout.css

So when you run $ git add-all you'll see your desired results: 因此,当您运行$ git add-all您将看到所需的结果:

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   .gitignore
    new file:   Test/in/a/unknown/folder/layout.css
    new file:   Test/layout.css

Note: You can find an explanation of why git add-all is the best way to add files to a git repo at http://lexsheehan.blogspot.com/2014/05/git-add-update.html 注意:您可以在http://lexsheehan.blogspot.com/2014/05/git-add-update.html上找到有关为什么git add-all是将文件添加到git repo的最佳方法的解释。

Quite old question but since I was struggling with this issue even now I figured I would share the actual solution to the problem. 这是一个非常古老的问题,但是由于我一直在努力解决这个问题,即使现在我仍想与我分享解决该问题的实际方法。

The thing is while you cannot commit empty directories in Git as if they were ignored, this rule does not apply to .gitignore . 问题是,您无法像在忽略Git中一样提交空目录时,此规则不适用于.gitignore

From https://git-scm.com/docs/gitignore 来自https://git-scm.com/docs/gitignore

A trailing "/**" matches everything inside . 尾部的“ / **”匹配里面的所有内容 For example, "abc/**" matches all files inside directory "abc", relative to the location of the .gitignore file, with infinite depth. 例如,相对于.gitignore文件的位置,“ abc / **”匹配目录“ abc”内的所有文件的深度是无限的。

A slash followed by two consecutive asterisks then a slash matches zero or more directories. 斜杠后跟两个连续的星号,然后斜杠匹配零个或多个目录。 For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. 例如,“ a / ** / b”匹配“ a / b”,“ a / x / b”,“ a / x / y / b”等。

** Matches everything inside - literaly everything - files AND directories. **匹配内部所有内容-几乎所有内容-文件和目录。

This leads us to another point in gitignore docs: 这将我们引到gitignore docs中的另一点:

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. 由于性能原因,Git不会列出被排除的目录,因此包含在文件上的任何模式无论在何处定义都无效。 Put a backslash ("\\") in front of the first "!" 在第一个“!”前面加上反斜杠(“ \\”)。 for patterns that begin with a literal "!", for example, "!important!.txt". 以文字“!”开头的模式,例如“!important!.txt”。

If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory. 如果该模式以斜杠结尾,则出于以下描述的目的将其删除,但它只会找到与目录匹配的内容。 In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in Git). 换句话说,foo /将匹配目录foo及其下的路径,但不会匹配常规文件或符号链接foo(这与pathspec通常在Git中的工作方式一致)。

Now, let's say we have a following dir structure: 现在,我们有以下目录结构:

/path/to/git/repo
|-- .gitignore
|-- /cache
    |-- somefile
    |-- README    
    |-- /dir
        |-- somefile2
        |-- README

And we want to ignore all files inside cache/ except for README files. 而且我们要忽略cache /内的所有文件(自述文件除外)。

If we specify gitignore like this: 如果我们这样指定gitignore:

/cache/**
!README

Git will ignore everything except for /cache/README . Git将忽略/cache/README以外的所有内容。 The other README won't show up because its directory /cache/dir was excluded with /cache/** and !README won't even apply to it. 其他自述文件将不会显示,因为它的目录/cache/dir/cache/**排除在外, !README甚至不适用于它。 To solve the issue we need to specify gitignore as this: 为了解决这个问题,我们需要指定gitignore为:

# Ignore everything inside cache/ dir
/cache/**
# Except for subdirectories(won't be commited anyway if there is no commited file inside)
!/cache/**/
# And except for README files
!README

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM