将正则表达式语法转换为 glob(从 Mercurial 切换到 Git)

Convert regex syntax to glob (switching from Mercurial to Git)

因为 Bitbucket 正在逐渐减少对 Mercurial 的支持,所以我在一些项目上从 Mercurial 切换到 Git。这看起来很简单,但我认为我需要对我的 .hgignore 文件进行一些手动更改,以便它们可以用作 .gitignore,因为它们使用我认为 Git 不支持的正则表达式语法.

我不得不说我不清楚如何使模式仅适用于根级别。我希望有人能给我 .hgignore 中的以下示例行的 glob 等价物:

\.project
\.settings/
\.idea/
^out/
web-app/WEB-INF/classes

Mercurial 的 .hgignore 确实比 Git 的 .gitignore 灵活(很多),因为 Mercurial 支持正则表达式 全局语法。然而,glob 语法往往更容易正确,我什至在 Mercurial 中也推荐它(它以前很慢,但现在 globs 在内部被翻译成正则表达式,所以应该没有真正的速度损失)。

\.project 等价于 .project1 \.settings/ 等价于 .settings/。这也适用于 .idea/。这里唯一稍难的是^out/web-app/WEB-INF/classes。你肯定想要:

/out/

在 Git 中将 out/ 部分锚定到 .gitignore 文件出现的级别,而您 可能 想要一个简单的:

web-app/WEB-INF/classes

除非你想匹配双名称组件系列 web-app/WEB-INF 在此点下方的任何级别,除非你想在那之后匹配 classes.*(以正则表达式形式)。在这些情况下,您可能需要:

**/web-app/WEB-INF/classes*

或类似的。前导 **/ 的原因是在 Git .gitignore 文件中,任何带有 embedded 斜杠的 glob 模式都等同于以前导斜线。即:

$ cat .gitignore
foo

这告诉 Git 不要抱怨位于 此点 以下任何级别的名为 foo 的文件或目录,即在此文件夹或任何子文件夹。另一方面:

$ cat .gitignore
/foo

的意思是只有foo在顶层,这对大家来说也是有道理的。但奇怪的是:

bar/foo

的意思完全一样:

/bar/foo

因为嵌入的(不是尾随的)斜杠表示 "match only in this folder",就像前导斜杠一样。

(Trailing 斜杠表示 "only a subdirectory / sub-folder should match this rule"。它们只是为了 "is there a slash" 测试而被删除;如果在删除任何尾随后有斜杠,则整个东西都固定在这个特定的文件夹/目录中。)


1如果我需要更多的弹药来支持 glob 而不是正则表达式,\.project 可能是 错误的 因为它也是排除名为 this.project.file 的文件。但是如果你真的 did 意味着 ^.*\.project.*$ 的等价物,那很难用 glob 模式来表达。