所以我想在我的项目中找到NLog的使用,我使用git grep为我这样做,但它发现了比我需要的更多的情况:
git grep NLog
GETA.Seo.Sitemap/Geta.SEO.Sitemaps.csproj: <Reference Include="NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
GETA.Seo.Sitemap/Geta.SEO.Sitemaps.csproj: <HintPath>..\packages\NLog.2.1.0\lib\net45\NLog.dll</HintPath>
GETA.Seo.Sitemap/Services/CloudinaryService.cs: NLogger.Exception("Could not transform image", exception);
GETA.Seo.Sitemap/Services/CloudinaryService.cs: NLogger.Warn("Url for cloudinary id was null");
GETA.Seo.Sitemap/Services/CloudinaryService.cs: NLogger.Warn("Could not locate file object for cloudinary id in EpiServer");
....
etc
当然,它找到了我想要的东西,但我想过滤到仅以.cs
结尾的文件。所以我试着这样做:
git grep NLog **/*.cs
Web/Global.asax.cs: NLogger.Info("Meny application start");
只有一次命中,我上面列出的两场比赛都没有列出。我发现这个很奇怪,我可能误解了git grep的全局匹配。有人可以启发我吗?
答案 0 :(得分:3)
(术语说明,对于阅读此答案的任何人:扩展*.cs
之类的东西称为“globbing”, 1 ,*.cs
是“shell glob”。“ shell“是你的命令行解释器,可以是sh
,bash
,zsh
,dash
,tcsh
等等.Git将有自己的内置的globbing。扩展的字符称为通配符,它们包括*
,?
和[
。有些shell也会对{
进行处理特别是,当使用Git的 reflog 名称时,这是一个问题,例如master@{yesterday}
或stash@{2}
。所有这些都可以使用引用。)
在这个特殊情况下的问题 - 它可能会或可能不会发生在其他人身上,这取决于他们使用的shell和他们的情况 - 是一个未受保护的(未引用的)*
经历了shell globbing。一些shell,比如bash,将会或者至少可以像Git那样扩展**
,意思是“递归到子目录”。其他人不能,或取决于设置,不会。 2
如果您的shell扩展**/*.cs
以包含名称Web/Global.asax.cs
但不包括GETA.Seo.Sitemap/Services/CloudinaryService.cs
(因为这是另一个级别的目录),那么当Git获取名称时,为时已晚:通配符*
字符消失了。 Git永远不会看到它们,也不能做自己的游戏。
简单的解决方案是通过引用来保护通配符不受shell通配:
git grep '**/*.cs'
(配对双引号 - 如git grep "**/*.cs"
- 也适用于大多数shell,前缀反斜杠在使用而不是引号时也可以工作,如git grep \*\*/\*.cs
中所示:只需保护每个易受攻击的字符反斜杠)。对于许多Git命令 - 它对于git grep
并不那么重要,除非你正在使用旧的提交 - 最好始终保护所有通配符,以便它们传递给Git,因为Git会扩展它们< em>针对当前工作树以外的其他内容。 shell只能看到工作树。 3 )
虽然它依赖于shell,但有时候通配符会匹配 nothing ,然后才能通过。例如,如果您没有名为sub
的目录并且您编写sub/*
,则某些(而不是所有)shell会将文字文本sub/*
传递给您运行的命令。 4 < / sup>在这种情况下,如果命令是Git命令,它可以再次执行自己的globbing。依赖于此并不明智,因为只要 要匹配的东西,shell就会进行匹配,而不是将原始通配符传递给程序。
1 名称“glob”从“global”缩短,在早期的shell中,由名为glob
的外部程序完成。 Early versions of Unix ran on machines with as little as 64 kilobytes of memory,因此没有太多空间来进行壳内扩展。有关详情,请参阅https://en.wikipedia.org/wiki/Glob_(programming)。
2 在bash中,通过设置变量globstar
来控制Git样式的扩展。
3 这甚至可能包含.git
存储库子目录本身,这通常很糟糕。在bash中,这由变量dotglob
控制。
4 在bash中,这由failglob
控制。
请注意,bash几乎提供了每个可能shell的所有可能行为。它试图成为一种通用的外壳。当然,这意味着它也需要所有这些控制变量,这使得bash相当大。您永远无法在64K非拆分I&amp; D PDP-11上运行它。