.hgignore正则表达式语法在任何地方忽略特定文件(例如“核心”)

时间:2017-07-22 06:57:51

标签: mercurial hgignore

假设我有一个这样的工作目录:

  1. T.C
  2. 多核
  3. TEST1 /芯
  4. 我想忽略所有“核心”文件。

    • 如果我使用“/ core $”(4)将被忽略但不会被忽略(2)。
    • 如果我使用“^ core $”(2)将被忽略但不会被忽略(4)
    • 如果我使用“core $”(2)和(4)将被忽略,但(3)也不会是我想要的。

    你是怎么做到的?

2 个答案:

答案 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(和Per​​l)正则表达式允许“负向后观”,即,只要某些模式不出现,就可以说“。因此,我们可以用以下内容替换现有的.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