假设我有一个这样的工作目录:
我想忽略所有“核心”文件。
你是怎么做到的?
答案 0 :(得分:3)
planetmaker's answer,“使用glob语法”,更简单,也是我通常会推荐的。但是,有一个正则表达式的答案,以及glob语法版本中的一个小缺陷。
Mercurial使用Python正则表达式,因此我们可以使用(alt1|alt2|...)
语法。请注意,这些是分组的。 1 我们可以而且应该使用(?:...)
来避免在需要时对进行分组,但对于.hgignore
,分组无关紧要,所以只使用括号更简单(也更可读),我在下面尽可能这样做。
我们可以写:
^core$
/core$
忽略文件core
,其前面没有任何内容(第一个模式),并忽略名称为test1/core
的文件(第二个模式)。这很好,但我们可以使用交替语法将其压缩一点。领先的^
甚至可以在一个组中的替代中起作用,只要它仍然实际上是领先的,所以:
(^|/)core$
表示同样的事情并使用regexp语法完成工作。
令人讨厌的是,所有这些模式都忽略了名为core
的任何目录中的所有文件(无论我们是否使用regexp vs 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
问题在于,只要我们说 ignore(某个匹配名为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$
作为我们的正则表达式。
构建这些regexp是一种艺术形式,很少值得付出很多努力。 Glob语法几乎总是更简单,只要它足够,我更喜欢它。它曾经比regexp语法慢得多,但这已经在Mercurial 3.1中得到了修复。
1 Grouped ,这里,意味着在Python代码中,我们可以使用.groups()
方法来获取由这些部分匹配的字符串部分正则表达式。未分组的(?:...)
表达式不会影响.groups()
收集字符串部分的方式。正如脚注中的脚注一样,在编写Python(或Perl,或其他)代码时更是一个问题,而不是在.hgignore
或其他部分使用这些模式时。水银。
答案 1 :(得分:1)
尝试使用glob语法提供文件名:
syntax: glob
core
它给出了:
~/hg-test$ hg st -A
M .hgignore
? multicore
I core
I dir1/core