简体   繁体   English

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

[英]Why does glob pattern with double asterisk not match anything in subdirectories?

I'm trying to write a .gitignore rule to exclude some files in a particular directory that has multiple levels of subdirectories. 我正在尝试编写一个.gitignore规则来排除具有多个子目录级别的特定目录中的某些文件。

The folder structure looks something like this: 文件夹结构如下所示:

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

(etc.)

I would like to keep the .keepme files (so that Git saves the directory structure), so I figure I'll write a rule to match anything under out that matches the pattern ?*.* : 我想保持.keepme文件(这样的Git保存的目录结构),所以我想我会写一个规则下匹配任何out匹配模式?*.*

out/**/?*.*

However, this does not match any files. 但是,这与任何文件都不匹配。

I thought that ** will match any number of subdirectories; 我认为**将匹配任意数量的子目录; why is this not working? 为什么这不起作用?

I'm running Git 1.8 in Bash 4.2 on a Fedora 18 VM. 我在Fedora 18 VM上运行Bash 4.2中的Git 1.8。

First, make sure you are using Git 1.8.2 or up, since that's when ** support was introduced. 首先,请确保您使用的是Git 1.8.2或更高版本,因为这是**支持的引入。

It sounds like you're trying to exclude .keepme files by matching *.* . 听起来你正试图通过匹配*.*来排除.keepme文件。 However, since * matches zero or more characters, it matches the empty string in front of the period in .keepme , including this file as well. 但是,由于*匹配零个或多个字符,它匹配.keepme.keepme前面的空字符串,包括此文件。

Maybe you intended it to work like out/**/?*.* 也许你打算像out/**/?*.*一样工作out/**/?*.*

If you'd like to match all non-dotfiles, you can use out/**/[!.]* which will also include filenames without periods in them, like Makefile . 如果你想匹配所有非dotfiles,你可以使用out/**/[!.]* ,它还包括没有句号的文件名,比如Makefile

I think that other guy's answer is a good lead. 我认为其他人的答案是好的领先。 The pattern out/**/[!.]*.* , which should match everything that contains a period and does not start with a period, also works in my test in bash, Arch Linux: 模式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

EDIT: It seems this actually doesn't work in the git bash bundled with the Windows version of git, there none of the above files are ignored by this .gitignore . 编辑:似乎这实际上不适用于与Windows版本的git捆绑在一起的git bash,这个.gitignore没有忽略上述任何文件。

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

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