如何在macOS上使用Homebrew安装支持PCRE的Git?

11

当我运行时

$ git grep -P "<pattern>"

我遇到了以下错误:

致命错误:未使用USE_LIBPCRE编译时无法使用Perl兼容正则表达式

我该如何正确地为macOS安装支持PCRE的Git?

3个回答

25

使用homebrew,只需执行如下命令:

brew reinstall --with-pcre2 git

它强制从源代码构建git而不是下载二进制瓶装包,但确保更新将使用pcre支持完成。


在我的MacOS 10.12,Git 2.12上运行良好。虽然两种方法都是有效的,但我更喜欢这种更简洁的修复方式,因为它可以在Git的brew升级后继续使用。 - Casey Watson
1
现在是2018年3月:警告:git:--with-pcre已被弃用;改用--with-pcre2! 因此,您必须执行brew reinstall --with-pcre2 git - akhaku
更新完毕。谢谢! - Gaëtan Lehmann
2
对我没用。它说这个选项无效。brew upgrade git解决了问题。 - Guy
brew upgrade git 对我也起作用了。为了提供更多信息,我使用的是git 2.19.1版本,它不支持 --with-pcre2。在升级到 2.22.0_1 版本时,添加了pcre2支持(ver 2-10.33)。话虽如此,在升级后,错误仍然显示。如果我找到一个可行的解决方案,我会更新这个信息。 - Matthew Setter

6

Homebrew 默认使用预编译版本(bottle)的 Git。如果需要启用 PCRE 支持,您需要从源代码编译 Git:

$ brew install pcre
$ export USE_LIBPCRE=yes
$ brew reinstall --build-from-source git

现在它应该按预期工作。

顺便说一下,这在我的OS X 10.10.2系统上没有起作用 - git仍然抱怨它没有使用pcre编译。但是Gaëtan Lehmann的更直接的答案(brew reinstall --with-pcre git)有效。 - jacobsa
1
请注意,每次运行 brew upgrade 时都需要运行此命令。请采用Gaëtan的答案。 - Casey Watson

2

自 Git 2.18(2018 年第二季度)起,构建选项已经发生了变化:

Git 可以构建为使用 PCRE 库的 v1 或 v2 版本。到目前为止,构建时配置 USE_LIBPCRE=YesPlease 指示构建过程使用 v1,但现在它表示使用 v2。

USE_LIBPCRE1USE_LIBPCRE2 可以用于明确选择要使用的版本,与以前一样。

查看 提交 e6c531b, 提交 a363f98, 提交 a91b113 (2018年3月11日),作者为 Ævar Arnfjörð Bjarmason (avar)
(由 Junio C Hamano -- gitster --提交 cac5351 中合并,于2018年4月9日)

Makefile:使USE_LIBPCRE=YesPlease表示v2而不是v1

USE_LIBPCRE标志从USE_LIBPCRE1的别名更改为USE_LIBPCRE2的别名。
当在我的94da919(“grep:add support for PCRE v2”,2017-06-01,Git v2.14.0-rc0)中添加对v2的支持时,现有的USE_LIBPCRE标志被留作表示v1,附带一条说明,说明这可能会在未来版本中更改。可选的v2支持首次进入Git版本2.14.0。
已经证明PCRE v2支持是稳定的,并且上游PCRE项目高度鼓励下游用户迁移到v2,因此让那些没有听说过PCRE v2的Git打包人员进一步推动迁移到v2是有意义的。

随着Git 2.24(2019年第四季度)的推出,PCRE v2支持得到了改进。

请参阅提交c581e4a(2019年8月18日),由Beat Bolli (bbolli)提交。
建议来自:Johannes Schindelin (dscho)
请参阅提交870eea8提交8a59998提交09872f6提交8a35b54提交685668f提交3448923提交04bef50(2019年7月26日)、提交b65abca提交48de2a7提交45d1f37提交2575412提交d316af0提交471dac5提交f463beb提交b14cf11(2019年7月1日)以及提交4457018提交4e2443b(2019年6月27日),均由Ævar Arnfjörð Bjarmason (avar)提交。
建议来自:Johannes Schindelin (dscho)
(由Junio C Hamano -- gitster --提交a73f917中合并,2019年10月11日)

grep:使用PCRE v2进行优化的固定字符串搜索

使用PCRE v2作为可选后端,重新引入了针对“grep”进行优化的固定字符串搜索。如前所述,使用kwset时比PCRE v1和v2 JIT慢,因此该优化是适得其反的。
这将恢复对“--fixed-strings”的优化,而不改变具有模式中的NUL字节的语义。正如在本系列的先前提交中所看到的那样,我们现在可以支持它,但我宁愿将那种边缘情况放在一边,这样我们就不会根据我们正在使用的“--fixed-strings”后端而有一个行为或另一个行为。这使得行为更难以理解和记录,并使得不同后端的测试更加痛苦。
当使用“log”的“--encoding”选项并且内容/命令行中的heystack/needle没有匹配的编码时,这确实会改变非C语言环境下的行为。请参见本系列中“t4210: skip more command-line encoding tests on MinGW”中的最近更改(following this discussion)。我认为这没关系。在那之前我们没有做任何明智的事情(只是比较了没有希望匹配的原始字节)。
至少现在用户会对为什么他们的grep/log在这种边缘情况下从未匹配到有些想法。

测试用例已在 Git 2.25(2020年第一季度)进行了调整。

请查看由Todd Zullinger (tmzullinger)于2019年11月30日提交的提交 e714b89
请查看由Andreas Schwab (andreas-schwab)于2019年11月26日提交的提交 c74b3cb
(已于2019年12月10日合并至提交 dac30e7,由Junio C Hamano -- gitster --执行)

t7812: 针对无效的UTF-8数据,期望使用grep -i失败

签名:Todd Zullinger

当添加/调整“使用无效UTF-8数据进行grep”测试时,它们缺乏重定向,导致它们在大多数系统上错误地成功,这发生在8a5999838e(“grep:在无效的UTF-8数据上对PCRE v2进行压力测试”,2019-07-26,Git v2.24.0-rc0 - 合并列在批次#8中)和870eea8166(“grep:不要在固定匹配上进入PCRE2_UTF模式”,2019-07-26,Git v2.24.0-rc0 - 合并列在批次#8中)。在禁用JIT的系统上,“grep -i”测试失败,因为它从未到达缺少重定向的部分。最近的补丁增加了缺失的重定向,并暴露了“PCRE v2:从无效的UTF-8数据中grep非ASCII字符与-i”测试失败的事实,无论是否启用JIT。基于870eea8166中的最后一段落:“当grep非ASCII固定字符串时。这是一个更一般的问题,很难修复,但我们至少可以修复最常见的情况,即在没有“-i”的情况下grep固定字符串。我想不出为什么我们会在这样逐字匹配时打开PCRE2_UTF。”它似乎我们不希望大小写敏感的grep成功。调整测试以反映这种期望。

而且:

请参见提交 7187c7b(由Ed Maste (emaste)于2019年11月27日提交)。
(由Junio C Hamano -- gitster --提交 b089e5e中合并,2019年12月10日)

t4210:跳过在FreeBSD上无法运行的国际化测试

签名作者:Ed Maste

A number of t4210-log-i18n tests added in 4e2443b181 set LC_ALL to a UTF-8 locale (is_IS.UTF-8) but then pass an invalid UTF-8 string to --grep.
FreeBSD's regcomp() fails in this case with REG_ILLSEQ, "illegal byte sequence," which git then passes to die():

fatal: command line: '�': illegal byte sequence

When these tests were added the commit message stated:

| It's possible that this  
| test breaks the "`basic`" and "`extended`" backends on some systems that  
| are more anal than `glibc` about the encoding of locale issues with  
| POSIX functions that I can remember

which seems to be the case here.

Extend test-lib.sh to add a REGEX_ILLSEQ prereq, set it on FreeBSD, and add !REGEX_ILLSEQ to the two affected tests.


由于FreeBSD不是唯一一个在输入无效的UTF-8时报告REG_ILLSEQ错误的平台,因此在Git 2.28(2020年第3季度)中添加逻辑以自动检测并跳过受影响的测试。

查看提交 c4c2a96, 提交 aba8187 (2020年5月18日) 由Carlo Marcelo Arenas Belón (carenas)完成。
(由Junio C Hamano -- gitster --合并于提交 f4cec40, 2020年6月9日)

t4210:动态检测REG_ILLSEQ并跳过受影响的测试

协助者:Eric Sunshine
签名作者:Carlo Marcelo Arenas Belón

7187c7bbb8 ("t4210: 跳过在FreeBSD上无法工作的i18n测试", 2019-11-27, Git v2.25.0-rc0 -- 合并列在批次#5中) 添加了一个REG_ILLSEQ先决条件,并通过复制test-lib中的公共分支并将其扩展到FreeBSD的特殊情况来实现。

相反,使用先前添加的test-tool扩展测试它,并与识别regcomp/regexec将被调用的破碎模式一起使用以避免任何依赖未定义行为的测试。

已更正第一个不准确的测试的描述,并为清晰度重新排列了测试,包括避免过长行的帮助程序。

仅受影响的引擎将被压制其测试,如果不可用,则包括使用LIBPCRE2的PCRE优化自b65abcafc7 ("grep: 使用PCRE v2进行优化的固定字符串搜索", 2019-07-01, Git v2.24.0-rc0 -- 合并列在批次#8中)。


在 Git 2.31(2021年第一季度)中,失去了可能在过去有用但现在不再有用的调试辅助工具,在“grep”代码路径中。

请参见 提交15c9649(由Ævar Arnfjörð Bjarmason (avar)于2021年1月26日提交)。
(由Junio C Hamano -- gitster --于2021年2月10日在提交c9f94ab中合并)

grep/log:移除隐藏的--debug--grep-debug选项

签名作者:Ævar Arnfjörð Bjarmason

Remove the hidden "grep --debug" and "log --grep-debug" options added in 17bf35a ("grep: teach --debug option to dump the parse tree", 2012-09-13, Git v1.8.0-rc0 -- merge).

At the time these options seem to have been intended to go along with a documentation discussion and to help the author of relevant tests to perform ad-hoc debugging on them.

Reasons to want this gone:

  1. They were never documented, and the only (rather trivial) use of them in our own codebase for testing is something I removed back in e01b4da ("grep: change non-ASCII -i test to stop using --debug", 2017-05-20, Git v2.14.0-rc0 -- merge listed in batch #5).

  2. Googling around doesn't show any in-the-wild uses I could dig up, and on the Git ML the only mentions after the original discussion seem to have been when they came up in unrelated diff contexts, or that test commit of mine.

  3. An exception to that is c581e4a (grep: under --debug, 2019-08-18, Git v2.24.0-rc0 -- merge listed in batch #8) (grep: under --debug, show whether PCRE JIT is enabled, 2019-08-18) where we added the ability to dump out when PCREv2 has the JIT in effect.
    The combination of that and my earlier b65abca ("grep: use PCRE v2 for optimized fixed-string search", 2019-07-01, Git v2.24.0-rc0 -- merge listed in batch #8) means Git prints this out in its most common in-the-wild configuration:

    $ git log  --grep-debug --grep=foo --grep=bar --grep=baz --all-match
    pcre2_jit_on=1
    pcre2_jit_on=1
    pcre2_jit_on=1
    [all-match]
    (or
     pattern_body<body>foo
     (or
      pattern_body<body>bar
      pattern_body<body>baz
     )
    )
    
    $ git grep --debug \( -e foo --and -e bar \) --or -e baz
    pcre2_jit_on=1
    pcre2_jit_on=1
    pcre2_jit_on=1
    (or
     (and
      patternfoo
      patternbar
     )
     patternbaz
    )
    

I.e.
for each pattern we're considering for the and/or/--all-match etc.
debugging we'll now diligently spew out another identical line saying whether the PCREv2 JIT is on or not.

I think that nobody's complained about that rather glaringly obviously bad output says something about how much this is used, i.e.
it's not.

The need for this debugging aid for the composed grep/log patterns seems to have passed, and the desire to dump the JIT config seems to have been another one-off around the time we had JIT-related issues on the PCREv2 codepath.
That the original author of this debugging facility seemingly hasn't noticed the bad output since then is probably some indicator.


从Git 2.31(2021年第一季度)开始,已停止支持已弃用的PCRE1库。

参见提交 7599730提交 0205bb1(2021年1月24日),由Ævar Arnfjörð Bjarmason (avar)完成。
(由Junio C Hamano -- gitster --提交 0199c68中合并,2021年2月10日)

7599730b7e:移除对PCRE库v1的支持

签名作者:Ævar Arnfjörð Bjarmason

取消支持使用PCRE库的版本1。
上游已经长期不建议使用它,并且处于仅限错误修复状态。
特别是依赖v1的人在e6c531b(Makefile: make USE_LIBPCRE=YesPlease表示v2,2018-03-11,Git v2.18.0-rc0——在batch #1列出的合并)中得到了移动到v2的暗示。v2首次作为v2.18.0的一部分发布。
这样LIBPCRE2测试前提条件就不再需要PCRE了。
但出于自我文档目的,我会保留它,以避免与其他正在进行的PCRE补丁冲突。
我也不会将我们自己的所有“pcre2”名称更改为“pcre”,即6d4b574("grep:将内部pcre变量和函数名更改为pcre1",2017年5月25日,Git v2.14.0-rc0——在batch #5列出的合并)的反义词。
我认为这没有意义,而且使历史/责备更难读懂。
也许如果有PCRE v3会考虑这个问题...

在Git 2.31(2021年第一季度)中,PCRE2对无效的UTF-8支持已进行更新。

请参见提交95ca1f9提交a4fea08(由Ævar Arnfjörð Bjarmason (avar)于2021年1月24日完成)。
(由Junio C Hamano -- gitster --于2021年2月10日合并至提交59ace28

grep/pcre2:更好地支持无效的UTF-8的搜索串

签名 by: Ævar Arnfjörð Bjarmason

在使用PCREv2后端时,针对包含无效UTF-8的目标字符串且模式串为非ASCII字符集,改进支持。这是一个更完整的修复,我开始修复它在870eea8(“grep:不要在固定匹配上进入PCRE2_UTF模式”,2019年7月26日,Git v2.24.0-rc0 - merge列在batch #8中)中,现在PCREv2有了PCRE2_MATCH_INVALID_UTF模式,我们可以利用它。这解决了8a59998(“grep:在无效的UTF-8数据上对PCRE v2进行压力测试”,2019年7月26日,Git v2.24.0-rc0 - merge列在batch #8中)中描述的情况,即:
  • 主题字符串是非ASCII字符集(例如“ævar”)
  • 我们处于is_utf8_locale()下,例如"en_US.UTF-8",而不是“C”
  • 我们使用了--ignore-case,或者我们是一个非固定模式
如果满足这些条件并且我们找到了无效的UTF-8数据,则PCREv2可能会出错,在实践中,这只发生在JIT后端下(默认情况下在大多数平台上启用)。最终,这解决了b65abca(“grep:使用PCRE v2进行优化的固定字符串搜索”,2019年7月1日,Git v2.24.0-rc0 - merge列在batch #8中)中的“回归”问题,我在引号中放置它是因为在那之前,我们也没有正确支持这些复杂的大小写折叠、区域设置等情况。它只是以不同的方式崩溃。与此相关的一个错误是在PCREv2 10.36中修复的PCRE2_NO_START_OPTIMIZE标志错误。可以通过设置PCRE2_NO_START_OPTIMIZE标志来解决它。让我们在这些情况下做到这一点,并为该错误添加测试。

随着Git 2.32(2021年第二季度)的推出,现在对使用pcre2库(版本为V2)的内存分配代码进行了更新。

请查看由Ævar Arnfjörð Bjarmason (avar)于2021年2月18日提交的提交c176035, 提交cbe81e6, 提交8d12851, 提交b76bf27, 提交797c359, 提交a39b400, 提交588e4fb, 提交47eebd2, 提交1cfc5a8, 提交0ddf8ce
(由Junio C Hamano -- gitster --合并于2021年3月22日提交24119d9)

grep/pcre2: 将回到仅线程 PCREv2 结构

Signed-off-by: Ævar Arnfjörð Bjarmason

"pcre2_general_context"的设置更改为在compile_pcre2_pattern()中每个线程执行,而不是在grep_init()中执行。
这个改变使它和grep_pat结构中其他pcre2_*成员的设置方式保持一致。
正如在前面的提交中指出的那样513f2b0("grep: make PCRE2 aware of custom allocator", 2019-10-16, Git v2.24.0-rc1 -- merge listed in batch #11),在分配pcre2_general_context时所采用的方法似乎最初是基于对PCREv2内存分配工作原理的误解。
grep_init()中创建全局上下文的方法仅增加了几乎没有收益的复杂性。
在我的系统上,每个线程可以节省24字节。
相比之下,PCREv2将为其自己的本地状态分配至少1KB。
正如6d423dd("grep: don't redundantly compile throwaway patterns under threading", 2017-05-25, Git v2.14.0-rc0 -- merge listed in batch #9)中所指出的那样,为了不试图微调分配,grep代码故意不通过例如在全局范围内共享一些PCREv2结构并使其他结构线程本地化。
因此,让我们删除这个特殊情况,并使所有成员再次变为线程本地的,以简化处理。
随着这个改变,我们可以将pcre2_{malloc,free}函数移动到更接近它们当前使用的位置。
请参见94da919("grep: add support for PCRE v2", 2017-06-01, Git v2.14.0-rc0 -- merge listed in batch #9)中有关线程安全性的讨论,以及约翰尼斯的评论表明我们应该做这个补丁所做的事情。
在禁止动态生成代码的环境(例如SELinux)中,预计JIT pcre模式失败。在这种情况下,退回到解释执行。
请参见提交50b6ad5(2023年1月31日),由Mathias Krause(mathiaskrause提交。
(由Junio C Hamano -- gitster --合并于提交214242a,2023年2月15日)

grep: 如果JIT内存分配失败,则回退到解释器

Cc: Carlo Marcelo Arenas Belón
Signed-off-by: Mathias Krause

Under Linux systems with SELinux's 'deny_execmem' or PaX's MPROTECT enabled, the allocation of PCRE2's JIT rwx memory may be prohibited, making pcre2_jit_compile() fail with PCRE2_ERROR_NOMEMORY (-48):

[user@fedora git]$ git grep -c PCRE2_JIT
grep.c:1

[user@fedora git]$ # Enable SELinux's W^X policy
[user@fedora git]$ sudo semanage boolean -m -1 deny_execmem

[user@fedora git]$ # JIT memory allocation fails, breaking 'git grep'
[user@fedora git]$ git grep -c PCRE2_JIT
fatal: Couldn't JIT the PCRE2 pattern 'PCRE2_JIT', got '-48'

Instead of failing hard in this case and making 'git grep'(man) unusable on such systems, simply fall back to interpreter mode, leading to a much better user experience.

As having a functional PCRE2 JIT compiler is a legitimate use case for performance reasons, we'll only do the fallback if the supposedly available JIT is found to be non-functional by attempting to JIT compile a very simple pattern.
If this fails, JIT is deemed to be non-functional and we do the interpreter fallback.
For all other cases, i.e.
the simple pattern can be compiled but the user provided cannot, we fail hard as we do now as the reason for the failure must be the pattern itself.
To aid users in helping themselves change the error message to include a hint about the '(*NO_JIT)' prefix.
Also clip the pattern at 64 characters to ensure the hint will be seen by the user and not internally truncated by the die() function.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接