Git diff:是否可以仅显示更改的行

问题描述 投票:0回答:7

我试图只获取已更改的行的新版本,而不是 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

可以吗?

git diff git-diff
7个回答
22
投票

仅添加行并不在所有情况下都有意义。如果你替换了一些文本块并且碰巧包含了之前存在的一行,那么 git 必须进行匹配和猜测。 通常,

git diff
的输出可以随后用作
patch
的输入,因此是有意义的。只有添加的行没有精确定义,因为 git 在某些情况下必须猜测。

如果您仍然想要它,则不能单独信任前导

+
符号(因为我们无法区分以
+++
开头的文件头和恰好以
++
开头的添加行)。也许过滤掉所有绿线会更好:

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

仅删除所有红线的行过滤器:

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

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

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

22
投票

如果您特别想要

new text
部分,请使用以下内容:

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

这基本上是您的代码,使用正则表达式通过管道传输到

egrep
命令。正则表达式将仅过滤以加号开头的行。

如果您想在脚本上下文中使用它作为别名,请确保转义转义字符。在您的

~/.gitconfig
文件中,添加:

[alias]
  diffaddedonly = !git diff HEAD --no-ext-diff --unified=0 --exit-code -a --no-prefix | egrep '^\\+'

9
投票

您可以使用:

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

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


5
投票

这是使用

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
    字符。

1
投票

如果您希望该过程自动进行,对于单个文件,您可以使用

diff
而不是
git diff
,执行 :

diff --changed-group-format='%>' --unchanged-group-format='' <( git show HEAD:myfile.ext ) myfile.ext
  • <( ) makes
    diff
    使用
    git show HEAD:myfile.ext
    的结果作为第一个输入
  • --changed-group-format='%>'
    告诉 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 执行它们)。

我在这个答案

中找到了这些差异选项

1
投票

不幸的是,颜色的东西不太能移植到 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 上测试)


-1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.