【问题标题】:Git diff: is it possible to show ONLY changed linesGit diff:是否可以仅显示更改的行
【发布时间】:2014-10-19 07:26:41
【问题描述】:

我正在尝试仅获取已更改的新版本行,而不是 git diff 显示的所有其他信息。

为:

git diff HEAD --no-ext-diff --unified=0 --exit-code -a --no-prefix

它显示:

diff --git file1 file2
index d9db605..a884b50 100644
--- file1
+++ file2
@@ -16 +16 @@ bla bla bla
-old text
+new text

我想看到的只是:

new text

有可能吗?

【问题讨论】:

  • 不,它不是重复的,@metacubed 我看到了这个问题并合并了答案,但它并没有完全帮助。我能够摆脱标题和尾随行,但不是所有其他信息。
  • 我根据您的具体问题添加了答案。

标签: git diff git-diff


【解决方案1】:

如果您只需要 new text 部分,请使用以下内容:

git diff HEAD --no-ext-diff --unified=0 --exit-code -a --no-prefix | egrep "^\+"

这基本上是您的代码,通过正则表达式输入egrep 命令。正则表达式将仅过滤以加号开头的行。

【讨论】:

  • git diff HEAD^^ --no-ext-diff --unified=0 --exit-code -a --no-prefix | egrep "^\-[^\-]"
【解决方案2】:

仅添加行并非在所有情况下都有意义。如果你替换了一些文本块,并且碰巧包含了之前存在的一行,那么 git 必须匹配和猜测。 - 通常git diff 的输出之后可以用作patch 的输入,因此是有意义的。只有添加的行没有精确定义,因为 git 在某些情况下必须猜测。

如果你仍然想要它,你不能单独相信一个领先的+ 标志。也许过滤所有绿线更好:

git diff --color=always|perl -wlne 'print $1 if /^\e\[32m\+\e\[m\e\[32m(.*)\e\[m$/'

for only deleted lines filter for all red lines:

git diff --color=always|perl -wlne 'print $1 if /^\e\[31m-(.*)\e\[m$/'

检查输出中您可以使用的颜色代码:

git diff --color=always|ruby -wne 'p $_'

【讨论】:

  • 为什么前面的“+”不可信?
  • 文件头以+++开头,如果你添加一行带有两个加号的行,你也会得到+++。你可以用更多的解析逻辑来解决这个问题,但只用绿线看起来更容易。
  • 啊,你完全正确。 git diff 输出中的“+”后面没有空格。我的错。
  • 太棒了!如何显示文件的已删除版本?
  • 使用git diff --color=always|perl -wlne 'print $1 if /^\e\[32m\+\e\[m\e\[32m(.*)\e\[m$/'|sed -r 's/\x1B\[m\x1B\[41m[[:blank:]]+//g' 删除尾随空格颜色代码。如果您使用的是 mac OS,请将 sed 替换为 docker run --rm -i hairyhenderson/sed
【解决方案3】:

你可以使用:

git diff -U0 <commit-hash> | grep "^\+\""

这将使您的输出为“+新文本”

【讨论】:

    【解决方案4】:

    这是使用grep 的答案。为了便于阅读,它保留了原始的红/绿颜色。我提供了一些语法变化:

    git diff --color | grep --color=never $'^\e\[3[12]m'
    git diff --color | grep --color=never $'^\033\[3[12]m'
    git diff --color | grep --color=never -P '^\e\[3[12]m'
    git diff --color | grep --color=never -P '^\033\[3[12]m'
    

    解释:

    • 需要git diff --color 以防止 git 在管道时禁用颜色。
    • grep --color=never 阻止 grep 突出显示匹配的字符串(这会从原始命令中删除原始颜色)
    • 匹配以红色 (\e[31m) 或绿色 (\e[32m) 转义码开头的行。
    • $'...'(ANSI-C 引用语法)或-P(perl 语法)是让grep\e\033 解释为ESC 字符。

    【讨论】:

      【解决方案5】:

      如果您希望该过程是自动的,对于单个文件,您可以使用diff 而不是git diff,这样做:

      diff --changed-group-format='%>' --unchanged-group-format='' <( git show HEAD:myfile.ext ) myfile.ext
      
      • diff 使用git show HEAD:myfile.ext 的结果作为第一个输入
      • --changed-group-format='%&gt;' 告诉 diff 输出添加的行
      • --unchanged-group-format='' 告诉 diff 对于删除的行不输出任何内容

      要获取提交信息(不是当前工作树修改),您甚至可以这样做

      diff --changed-group-format='%>' --unchanged-group-format='' <( git show _SHA_~:myfile.ext ) <( git show _SHA_:myfile.ext )
      

      其中_SHA_ 是对提交的任何引用(SHA、分支、标签...)

      (对于那些想知道我为什么需要这个的人:我有一个“update.sql”文件,其中放置了所有 SQL 语句。所以,在项目更新时,我必须找到添加了哪些行,让 Mysql 执行它们)。

      我在 this answer 中找到了这些差异选项

      【讨论】:

        【解决方案6】:

        不幸的是,颜色的东西不能移植到 Windows(使用 unxutils 支持的命令)。但是有一个解决方案可以通过使用颜色模式解决 +++ 问题。

        此外,我们可能也不想要主角。因此,一旦我们与它匹配,让我们使用 sed 摆脱它:

        git diff --no-ext-diff --unified=0 -a --no-prefix --output-indicator-new=% | sed -n "s/^%\(.*\)$/\1/p"

        如果你想删除行:

        git diff --no-ext-diff --unified=0 -a --no-prefix --output-indicator-old=% | sed -n "s/^%\(.*\)$/\1/p"

        通过将 % 替换为 +,您不必担心以 +++ 开头的标题行(b/c git 在那里不使用该前缀......但是这可能会改变,这仍然是一个瓷器命令)

        前缀字符必须是 ASCII(所以不要对 unicode 有兴趣)。鉴于 Windows/Linux/sed 语法的变幻莫测。我认为,唯一不需要在某处转义的 ASCII 字符是:%,_~

        根据您的需要,您可能希望删除 -a,因为二进制文件可能会造成混乱。

        --exit-code 在另一个答案中提到的是一个 noop。通过管道运行,我们只得到第二个退出代码(在 Windows 和 Linux 上测试)

        【讨论】:

          【解决方案7】:

          务实的方法:恢复旧版本(注意不要覆盖您的更改),并使用良好的旧差异。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-09-19
            • 2011-04-24
            • 2017-10-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-04-08
            • 2012-10-26
            相关资源
            最近更新 更多