假设我有一个像这样的工作目录:
- t.c
- 核心
- 多核
- 测试1/核心
我想忽略所有“核心”文件。
- 如果我使用“/core$”,(4) 将被忽略,但 (2) 不会。
- 如果我使用“^core$”,(2) 将被忽略,但 (4) 不会被忽略
- 如果我使用“core$”,(2) 和 (4) 将被忽略,但 (3) 也会被忽略,这不是我想要的。
你是如何做到这一点的?
最佳答案
planetmaker's answer ,“使用 glob 语法”更简单,也是我通常推荐的。然而,有一个正则表达式答案,并且 glob 语法版本中有一个小缺陷。
Mercurial 使用 Python 正则表达式,因此我们可以使用 (alt1|alt2|...)
语法。请注意,它们是分组的。1 我们可以而且应该使用 (?:...)
来避免分组在需要时,但是对于 .hgignore
,分组是无关紧要的,因此仅使用括号会更简单(并且更具可读性),我在下面尽可能这样做。
我们可以这样写:
^core$
/core$
忽略前面没有任何内容的文件core
(第一个模式),并忽略名称类似于test1/core
的文件(第二个模式)。这很好,但我们可以使用交替语法将其压缩得更多一些。前导 ^
即使在组内的替代中也可以工作,只要它实际上仍然是前导,因此:
(^|/)core$
表示同样的事情并使用正则表达式语法完成工作。
令人烦恼的是,所有这些模式都会忽略任何名为 core
的目录中的所有文件(无论我们是否使用 regexp 与 glob 语法):
$ rm core
$ mkdir core
$ touch core/keepme
$ cat .hgignore
syntax: glob
core
$ hg status -A
? .hgignore
? multicore
? t.c
I core/keepme
I test1/core
问题是,一旦我们说忽略(与名为core
的目录匹配的某种模式),如果中有文件对于当前未跟踪的目录,Mercurial 也会忽略它们。您可以强制添加文件 - 与 Git 一样,一旦跟踪文件,任何与其匹配的忽略文件模式都将变得无关紧要 - 但这对我们粘贴到目录中的其他文件没有帮助:
$ hg add core/keepme
$ touch core/keep-me-too
$ hg status -A
A core/keepme
? .hgignore
? multicore
? t.c
I core/keep-me-too
I test1/core
在这里,正则表达式可以证明是答案。 Python(和 Perl)正则表达式允许“负向后查找”,即,您可以说“只要某些模式不出现”。因此,我们可以将现有的 .hgignore
内容替换为:
$ cat .hgignore
(?<!^core/).*/core$
现在我们的状态是这样的:
$ hg status -A
A core/keepme
? .hgignore
? core/keep-me-too
? multicore
? t.c
I test1/core
这个特定的正则表达式取决于所需的 core
目录,该目录在顶层被命名为 core
(^core
)。如果我们想保留名为 core
(顶级)和 a/subsys/core
的核心目录,我们会这样写:
(?<!(^core|^a/subsys/core)/).*/core$
作为我们的正则表达式。
构建这些正则表达式是一种艺术形式,很少值得付出很多努力。 Glob 语法几乎总是更简单,只要它足够,我更喜欢它。它曾经比正则表达式语法慢得多,但这个问题在 Mercurial 3.1 左右得到了修复。
1Grouped,这里是指在Python代码中,我们可以使用.groups()
方法来获取分组的各个部分与正则表达式的这些部分匹配的字符串。非分组 (?:...)
表达式不会影响 .groups()
收集字符串各部分的方式。正如在脚注的段落中一样,在编写 Python(或 Perl 或其他)代码时,这更值得关注,而不是在 .hgignore 中使用这些模式时。或 Mercurial 的其他部分。
关于mercurial - .hgignore 正则表达式语法忽略任何地方的特定文件(例如 "core"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45251686/