为什么带有双星号的glob模式与子目录中的任何内容都不匹配?

时间:2013-07-01 19:12:36

标签: git gitignore glob

我正在尝试编写.gitignore规则来排除具有多个子目录级别的特定目录中的某些文件。

文件夹结构如下所示:

out
├─a
│ ├─source
│ │ ├─.keepme
│ │ ├─183597.txt
│ │ ├─271129.txt
│ │ └─288833.txt
│ └─parsed
│   ├─.keepme
│   ├─183597.csv
│   ├─271129.csv
│   └─288833.csv
├─b
│ └─(...)

(etc.)

我想保留.keepme个文件(以便Git保存目录结构),所以我想我会编写一个规则来匹配out下匹配模式{{1}的任何内容}}:

?*.*

但是,这与任何文件都不匹配。

我认为out/**/?*.* 将匹配任意数量的子目录;为什么这不起作用?

我在Fedora 18 VM上运行Bash 4.2中的Git 1.8。

2 个答案:

答案 0 :(得分:7)

首先,请确保您使用的是Git 1.8.2或更高版本,因为这是在引入**支持时。

听起来您正试图通过匹配.keepme来排除*.*个文件。但是,由于*匹配零个或多个字符,因此它匹配.keepme中句点前面的空字符串,包括此文件。

也许您打算像out/**/?*.*

那样工作

如果您想匹配所有非点文件,可以使用out/**/[!.]*,其中还包含没有句点的文件名,例如Makefile

答案 1 :(得分:0)

我认为其他人的答案是好的领先。模式out/**/[!.]*.*应该匹配包含句点的所有内容并且不以句点开头,也适用于我在bash中的测试,Arch Linux:

$ find * -type f
out/a/source/4232352.txt
out/a/source/1312312.txt
out/a/source/4234234.txt
out/a/source/.keepme
out/a/parsed/1231222.csv
out/a/parsed/9593343.csv
out/a/parsed/5675675.csv
out/a/parsed/.keepme
$ cat .gitignore
out/**/[!.]*.*

$ git init && git add -A && git status --ignored
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   .gitignore
#   new file:   out/a/parsed/.keepme
#   new file:   out/a/source/.keepme
#
# Ignored files:
#   (use "git add -f <file>..." to include in what will be committed)
#
#   out/a/parsed/1231222.csv
#   out/a/parsed/5675675.csv
#   out/a/parsed/9593343.csv
#   out/a/source/1312312.txt
#   out/a/source/4232352.txt
#   out/a/source/4234234.txt
编辑:看起来这实际上不适用于与Windows版本的git捆绑在一起的git bash,这个.gitignore没有忽略上述任何文件。