我有一个与一组文件名匹配的Python正则表达式。如何更改它以便我可以在Mercurial的.hgignore文件中使用它来忽略不匹配表达式的文件?
全文:
我有一个很大的源代码树,其中*.ml
个文件散布在各处。我想把它们放到一个新的存储库中。还有其他不太重要的文件太重,无法包含在存储库中。我正在尝试找到.hgignore
文件的相应表达式。
第一次观察:Python没有常规语言补语操作符(AFAIK它只能补充一组字符)。 (顺便说一句,为什么?)
第二次观察: Python中的以下正则表达式:
re.compile("^.*(?<!\.ml)$")
按预期工作:
abcabc - match
abc.ml - no match
x/abcabc - match
x/abc.ml - no match
但是,当我在.hgignore
文件中放置完全相同的表达式时,我得到了这个:
$ hg st --all
? abc.ml
I .hgignore
I abcabc
I x/xabc
I x/xabc.ml
根据.hgignore
联机帮助页,Mercurial只使用普通的Python正则表达式。那我怎么得到不同的结果呢?
Mercurial如何找到匹配x/xabc.ml
?
是否有人知道缺乏常规语言补语操作员的方式不那么丑陋?
答案 0 :(得分:1)
正则表达式依次应用于每个子目录组件以及文件名,而不是一次性应用于整个相对路径。因此,如果我的仓库中有/ b / c / d,则每个正则表达式将应用于a,a / b,a / b / c以及a / b / c / d。如果任何组件匹配,则将忽略该文件。 (您可以通过使用bar / foo尝试^bar$
来判断这是行为 - 您会看到bar / foo被忽略。)
^.*(?<!\.ml)$
忽略x / xabc.ml,因为模式匹配x(即子目录。)
这意味着没有可以帮助您的正则表达式,因为您的模式必须与第一个子目录组件匹配。
答案 1 :(得分:0)
通过一些测试,找到了两种似乎有效的解决方案。第一个根到一个子目录,显然这很重要。第二个是脆的,因为它只允许使用一个后缀。我正在使用Mercurial 1.2.1在Windows XP上运行这些测试(自定义工作更加单一)。
(我在# message
添加了评论。)
$ hg --version Mercurial Distributed SCM (version 1.2.1) $ cat .hgignore syntax: regexp ^x/.+(?<!\.ml)$ # rooted to x/ subdir #^.+[^.][^m][^l]$ $ hg status --all ? .hgignore # not affected by x/ regex ? abc.ml # not affected by x/ regex ? abcabc # not affected by x/ regex ? x\saveme.ml # versioned, is *.ml I x\abcabc # ignored, is not *.ml I x\ignoreme.txt # ignored, is not *.ml
第二个:
$ cat .hgignore syntax: regexp #^x/.+(?<!\.ml)$ ^.+[^.][^m][^l]$ # brittle, can only use one suffix $ hg status --all ? abc.ml # versioned, is *.ml ? x\saveme.ml # versioned, is *.ml I .hgignore # ignored, is not *.ml I abcabc # ignored, is not *.ml I x\abcabc # ignored, is not *.ml I x\ignoreme.txt # ignored, is not *.ml
第二个完全预期的行为,因为我理解OP。第一个只在子目录中有预期的行为,但更灵活。
答案 2 :(得分:0)
问题特别出现在子目录中的匹配与根目录不同。请注意以下事项:
$ hg --version
Mercurial Distributed SCM (version 1.1.2)
这是一个旧版本,但它的行为方式相同。我的项目有以下文件:
$ find . -name 'abc*' -print
./x/abcabc
./x/abc.ml
./abcabc
./abc.ml
这是我的.hgignore:
$ cat .hgignore
^.*(?<!\.ml)$
现在,当我运行stat
时:
$ hg stat
? abc.ml
因此,hg
无法接听x/abc.ml
。但这是正则表达式的问题吗?也许不是:
$ python
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mercurial.ignore
>>> import os
>>> root = os.getcwd()
>>> ignorefunc = mercurial.ignore.ignore(root, ['.hgignore'], lambda msg: None)
>>>
>>> ignorefunc("abc.ml") # No match - this is correct
>>> ignorefunc("abcabc") # Match - this is correct, we want to ignore this
<_sre.SRE_Match object at 0xb7c765d0>
>>> ignorefunc("abcabc").span()
(0, 6)
>>> ignorefunc("x/abcabc").span() # Match - this is correct, we want to ignore this
(0, 8)
>>> ignorefunc("x/abc.ml") # No match - this is correct!
>>>
请注意,ignorefunc
处理abcabc
和x/abcabc
相同(匹配 - 即忽略),而abc.ml
和x/abc.ml
也处理相同(不匹配) - 即不要忽视)。
所以,也许逻辑错误在Mercurial的其他地方,或者我正在考虑Mercurial的错误位置(尽管如果是这样的话我会感到惊讶)。除非我错过了什么,否则可能需要向Mercurial提交一个错误(而不是Martin Geisler指出的RFE)。