【问题标题】:git diff --ignore-matching-lines ignores all linesgit diff --ignore-matching-lines 忽略所有行
【发布时间】:2022-12-10 09:40:29
【问题描述】:

我正在尝试使用 git 的 --ignore-matching-lines,但遇到了一些奇怪的行为。这是普通 git diff 的输出:

$ git diff test.txt
diff --git a/test.txt b/test.txt
index 602c47d1cb..82655814c5 100644
--- a/test.txt
+++ b/test.txt
@@ -1,5 +1,7 @@
-Hello world
+Hello whitespace world
+
 
 Lots of blank lines
 
 Goodbye world
+

但是,如果我跑

$ git diff --ignore-matching-lines='^$' test.txt

我没有输出

为什么这会忽略添加单词whitespace 的更改?

【问题讨论】:

    标签: git diff


    【解决方案1】:

    这可能是由于“$”本身的解释方式引起的,如“How does git diff --ignore-matching-lines work”中所述,Sjoerd Langkemper(也是Stack Overflow user):

    Git 在每一行上运行每个正则表达式。
    这些行以换行符结尾,所以我们的正则表达式实际上是根据以下内容检查的:

    His bill will hold more than his belican,
    
    

    其中 代表换行符。

    当我们有一个添加空行的更改时,正则表达式将针对由 组成的单字节字符串运行。
    我们如何匹配它?

    使用--ignore-blank-lines之类的东西来忽略空行会更容易。

    (顺便检查一下,git diff --ignore-blank-line 在您的特定情况下是否是一个不错的选择)

    但是,这不能与我们想要忽略的其他正则表达式一起很好地工作。
    如果我们想忽略执行无趣的与腹部相关的更改和添加无趣的空行的更改,我们给-I 的正则表达式需要匹配两者才能隐藏更改。
    所以我们需要一个匹配空行的正则表达式,--ignore-blank-lines 和其他与空格相关的选项不会改变这一点。

    ^$ 不能匹配空行。

    • ^ 匹配行的开头和缓冲区的开头。
    • 类似地,$ 将行的结尾都匹配为缓冲区的结尾。

    所有更改的行都以换行符结束,就在缓冲区结束之前。
    这意味着^$匹配每一个改变的行.
    末尾的换行符开始一个新行,紧随其后的是缓冲区的末尾。

    … his belican,
    
                   ↑
                   ^ matches because 
     starts a new line
                   $ matches because the buffer ends here
    

    这可以解释为什么 --ignore-matching-lines='^$' 忽略了添加单词 whitespace 的更改:it is ignoring全部线!

    为了更精确地匹配,我们可以使用 to match the start of the buffer, and '` 来匹配缓冲区的末尾。
    因此,空行可以匹配:

     `
    '
    

    是一个实际的换行符,而不是 backslash-n
    这需要大量转义才能在 shell 中正确输入:

    git diff -I $'\`
    \'' …
    

    【讨论】:

      猜你喜欢
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      • 2016-07-18
      • 1970-01-01
      • 2016-03-24
      相关资源
      最近更新 更多