.gitignore排除不适用于单个文件

时间:2016-02-08 20:40:07

标签: git macos bash

$ git --version
git version 2.6.4

我意识到这是重复但另一个问题的答案没有帮助。

文件夹结构

/
-- dist/
---- samples/ 
---- README.md
---- foo/
---- bar/
---- baz.js 

除了示例和README.md之外,我想忽略dist中的所有内容。我的前几次尝试都没有用,所以我决定放弃自述文件:

dist
!dist/samples/README.md 

README是一个全新的文件。 dist文件夹根本不在源代码管理中。但是当我检查忽略时,它仍然被忽略:

$ git check-ignore dist/samples/README.md 
dist/samples/README.md
$ git check-ignore src
   # empty line    

我试过了:

  1. 更改忽略的顺序
  2. 从行首删除斜杠
  3. 在中间添加**:dist/**/README.md
  4. 在第一行的/*末尾添加dist
  5. 唯一被忽略的是* .js,* .js.map,temp和node_modules。有趣的是,Webstorm认为文件没有被忽略(它会改变颜色),但命令行工具确实认为它被忽略了。

    我看不出我做错了什么。模式似乎很简单:

    1. 忽略此目录中的所有内容
    2. 这里不要忽视这一点
    3. 但它显然不起作用。

3 个答案:

答案 0 :(得分:22)

问题只是因为您忽略了目录dist。所以Git将不再查看目录以查找其他文件。

this related answer中所述,您需要将目录列入白名单并仅忽略其内容。由于你有一个嵌套的结构,这最终会有点复杂:

# ignore everything in the `dist` folder
dist/*
# … but don’t ignore the `dist/samples` folder
!dist/samples/
# … but ignore everything inside that `dist/samples` folder
dist/samples/*
# … except the `README.md` there
!dist/samples/README.md

gitignore documentation(强调我的)中也明确提到了这一点:

  

可选前缀" !"否定了这种模式;之前模式排除的任何匹配文件将再次包含在内。 如果排除该文件的父目录,则无法重新包含文件。由于性能原因,Git不会列出排除的目录,因此所包含文件的任何模式都无效,无论如何它们的定义。

答案 1 :(得分:1)

我在子目录中的另一个.gitignore有类似的问题。例如:

- root
-- Subdir
--- gulpfile.js
--- .gitignore
-- .gitignore

在根.gitignore中有两个规则:

*.js
!gulpfile.js

Subdir/gulpfile.js中,另一个规则:

*.js

因此,Subdir/gulpfile.js被忽略。要解决问题,需要删除Subdir/.gitignore,或将!gulpfile.js添加到Subdir/.gitignore

答案 2 :(得分:0)

tl; dr:

/dist/**/*.*
!/dist/**/README.md
!/dist/samples/*.*

证明有效:

tree dist -a
dist
├── bar
│   └── index.html
├── baz.js
├── foo
│   └── main.js
└── samples
    ├── README.md
    └── stuff.jpg

find dist -type f | git check-ignore --verbose --non-matching --stdin
.gitignore:1:/dist/**/*.*   dist/baz.js
.gitignore:2:!/dist/samples/*.* dist/samples/stuff.jpg
.gitignore:2:!/dist/samples/*.* dist/samples/README.md
.gitignore:1:/dist/**/*.*   dist/foo/main.js
.gitignore:1:/dist/**/*.*   dist/bar/index.html

类似于https://stackoverflow.com/a/35279076/2496472的文档中提到:

可选的前缀“ !”使模式无效。先前模式排除的所有匹配文件将再次包含在内。如果排除该文件的父目录,则无法重新包含该文件。由于性能原因,Git不会列出被排除的目录,因此所包含文件上的任何模式都无效,无论它们在何处定义。

但是,文档还说:

两个与完整路径名匹配的连续星号(“ **”)可能具有特殊含义:

  • 一个斜杠后跟两个连续的星号,然后一个斜杠匹配零个或多个目录。例如,“ a/**/b匹配“ a/b”,“ a/x/b”,“ a/x/y/b”等等。

将它们放在一起,策略是从不忽略目录,而忽略目录中的所有文件,然后排除所需的文件。

参考:

相关问题