我对 Git 2.43 中的
--pickaxe-regex
行为感到失望。
diffcore 文档 声明如下(强调我的):
“-S
”检测原像和后像指定文本块出现次数不同的文件对。根据定义,它不会检测文件内移动。此外,当变更集在不影响感兴趣的字符串的情况下批量移动文件时,diffcore-rename 像往常一样启动,并且 忽略文件对(因为该字符串的出现次数在重命名检测到的文件对中没有改变) 。 与-S
一起使用时,将--pickaxe-regex
视为扩展的 POSIX 正则表达式来匹配, 而不是文字字符串。
但这似乎并不准确。我一直在 Python 存储库中比较这些测试命令的输出:
# Success: just text in the search block
git log --pickaxe-regex -S'def'
# Broken: some POSIX extended word boundaries
git log --pickaxe-regex -S'\bdef\b'
\b
换行不需要def
以字边界开始和结束。它只是中断搜索,因此不会返回任何结果。以防万一对逃跑有些困惑,我也尝试过-S'\\bdef\\b'
、
-S"\bdef\b"
和
-S"\\bdef\\b"
。它们都不返回结果,但
-S'def'
会返回结果。
# Broken: \s for a whitespace character
git log --pickaxe-regex -S'def\s'
# Success: [[:blank:]] for a whitespace character
git log --pickaxe-regex -S'def[[:blank:]]'
这是怎么回事?
\b
不是由 POSIX 定义的。它是 Perl、Ruby 和 PCRE 中存在的扩展。来自 Linux 上的
regex(7)
:
正则表达式(“RE”),如 POSIX.2 中定义,有两种形式:现代 RE(大致为 egrep;POSIX.2 称这些“扩展”RE)和过时 RE(大致为 ed(1) ); POSIX.2“基本”RE).POSIX 扩展 RE 支持
|
、
+
、
*
、
?
、
^
、
$
和边界(带大括号)。它们还支持带有字符类的括号。再次,来自
regex(7)
:
过时(“基本”)正则表达式在几个方面有所不同。 “|”、“+”和“?”是普通字符,并且没有等效的功能。边界的分隔符是“{” 和“}”,其中“{”和“}”本身是普通字符。嵌套子表达式的括号是“(”和“)”,其中“(”和“)”本身是普通字符。 '^' 是一个普通的 字符,除了在 RE 的开头或(!)带括号的子表达式的开头,“$”是普通字符,除了在 RE 的结尾或(!)带括号的子表达式的结尾之外。 sion,如果 '*' 出现在 RE 的开头或带括号的子表达式的开头(在可能的前导 '^' 之后),则它是普通字符。所有其他转义和功能基本上都是由 Perl 或 PCRE 定义的(包括普通的 C 转义,如
\t
和
\n
)。我不认为在镐功能中可以选择使用 PCRE,因此您需要发送补丁或坚持使用扩展 POSIX 正则表达式。