Git diff 仅显示已修改的行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18810623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 16:57:36  来源:igfitidea点击:

Git diff to show only lines that have been modified

git

提问by r3b00t

When I do a git diff, it shows lines that have been added:

当我执行 git diff 时,它显示已添加的行:

+ this line is added

lines that have been removed:

已删除的行:

- this line is removed

but it also shows many lines which are not modified:

但它也显示了许多未修改的行:

this line is not modified
this line is also not modified

This results in the actual git diff looking something like this:

这导致实际的 git diff 看起来像这样:

+ this line is added
  this line is not modified
- this line is removed
  this line is not modified

Can I ask git to show only lines that have been modified and ignore all other code which has not been modified? I have written a method which will remove all the lines which don't have a "+" or "-" sign in front of them, but I am sure there must be a simpler way to do this.

我可以要求 git 仅显示已修改的行并忽略所有其他未修改的代码吗?我编写了一个方法,可以删除所有前面没有“+”或“-”符号的行,但我确信必须有一种更简单的方法来做到这一点。

In my git diff, I am only interested in seeing the lines that have been modified.

在我的 git diff 中,我只对查看已修改的行感兴趣。

Thanks in advance.

提前致谢。

回答by Chris Hayes

What you want is a diff with 0 lines of context. You can generate this with:

您想要的是具有 0 行上下文的差异。您可以使用以下方法生成:

git diff --unified=0

or

或者

git diff -U0

You can also set this as a config option for that repository:

您还可以将其设置为该存储库的配置选项:

git config diff.context 0

To have it set globally, for any repository:

要全局设置它,对于任何存储库:

 git config --global diff.context 0

回答by user650654

Another hack (on un*x) to show just the lines beginning with +and -:

另一个 hack(在 un*x 上)只显示以+and开头的行-

git diff -U0 | grep '^[+-]' | grep -Ev '^(--- a/|\+\+\+ b/)'

The code above does the following:

上面的代码执行以下操作:

  • git diff -U0: choose 0 context lines
  • The first grep only includes all lines starting with +or -
  • The second grep excludes lines starting with --- a/or +++ b/
  • git diff -U0: 选择 0 个上下文行
  • 第一个 grep 只包括所有以+or开头的行-
  • 第二个 grep 排除以--- a/or开头的行+++ b/

Color

颜色

To show colored diff, try the following:

要显示彩色差异,请尝试以下操作:

git diff -U0 --color | grep '^\e\[[^m]*m[-+]' | grep -Ev '(--- a/|\+\+\+ b/)'
  • The expression, ^\e\[[^m]*m[-+], looks for start of line (^), then the escape characer (\e) followed by [which together start the escape sequence, then any character that is not an "m" (numbers, semicolons, or nothing), followed by an "m" which ends the escape sequence.
  • Note that all of the following are valid escape sequences: \e[0m(reset), \e[m(also reset), \e[1m(bold on), \e[31m(red), \e[32m(green), \e[9;31m(strike out + red), \e[31;9m(red + strike out), \e[1;4;9;31m(bold + underline + strike out + red). The default git colors use red and green, but they can be reconfigured.
  • --coloris the same as --color=always.
  • The restriction on --- a/or +++ b/to appear at the start of the line has been removed to accommodate for the escape sequences and this could lead to an edge case.
  • 的表达,^\e\[[^m]*m[-+],看上去为线(开始^),则逃逸characer( \e),随后[其一起启动转义序列,则任何字符不是一个“M”(数字,分号或无),接着是“ m" 结束转义序列。
  • 请注意,以下所有转义序列都是有效的转义序列:(\e[0m重置)、\e[m(也重置)、\e[1m(加粗)、\e[31m(红色)、\e[32m(绿色)、\e[9;31m(删除 + 红色)、\e[31;9m(红色 + 删除)、\e[1;4;9;31m(加粗 +下划线 + 删除 + 红色)。默认的 git 颜色使用红色和绿色,但它们可以重新配置。
  • --color与 相同--color=always
  • 已删除对--- a/+++ b/出现在行首的限制以适应转义序列,这可能会导致边缘情况。

Additional Notes:

补充说明:

  • The above solution needs to be modified if you use additional git diff options such as -R, --src-prefix, --dst-prefix, --no-prefix, etc.
  • The two greps can be combined into a single grep -E -v '^(\+\+\+ b/|--- a/|@@ |diff --git|index )', but I find the double grep version easier to understand.
  • 如果您使用其他 git diff 选项,例如, , , 等-R,则需要修改上述解决方案。--src-prefix--dst-prefix--no-prefix
  • 两个 grep 可以合并为一个grep -E -v '^(\+\+\+ b/|--- a/|@@ |diff --git|index )',但我发现双 grep 版本更容易理解。

回答by simleo

Following up on Chris' latest comment, the main problem with the post-processing is that you want to keep lines starting with -|+but you also want to filter out those that start with ---|+++. If you are storing patch files in your repo (I do, in Pydoop), on the other hand, you want to keep lines that start with --|++, so the regexp becomes a bit involved:

跟进 Chris 的最新评论,后处理的主要问题是您希望保留以 开头的行,-|+但也希望过滤掉以---|+++.开头的行。另一方面,如果您将补丁文件存储在您的存储库中(我在Pydoop存储),另一方面,您希望保留以 开头的行--|++,因此正则表达式变得有点复杂

git diff | grep -P '^\+(?:(?!\+\+))|^-(?:(?!--))'

The regexp uses a negative lookahead: see Peter Boughton's answer to this questionfor a detailed explanation.

正则表达式使用否定前瞻:有关详细解释,请参阅 Peter Boughton对此问题的回答。

If you do this often, you might want to set up a git alias for it:

如果你经常这样做,你可能想为它设置一个 git 别名:

git config --global alias.diffonly '!git diff | grep -P "^\+(?:(?!\+\+))|^-(?:(?!--))"'

回答by galois

I think for simple cases the regex can be much shorter and easier to remember, with the caveat that this won't work if you have line changes where the line itself starts with +or -

我认为对于简单的情况,正则表达式可以更短更容易记住,但需要注意的是,如果您在行本身以+-

$ git diff | grep '^[+|-][^+|-]'

The regex says the line should start with +or -, and the immediately following character should be neither of those. I got the same results whether I escaped the +or not here, btw...

正则表达式表示该行应以+or开头,-紧随其后的字符不应是这两者之一。无论我是否+在这里逃脱,我都得到了相同的结果,顺便说一句...



Example:

例子:

$ cat testfile
A
B
C
D
E
F
G

Say I change Cto X, Eto Y, and Gto Z.

说我的变化CXEY,并GZ

$ git diff | grep '^[+|-][^+|-]'
-C
+X
-E
+Y
-G
+Z

Like I said above, though, this is just for most cases. If you pipe that output to a file dout, then try the same regex, it won't work.

不过,就像我上面所说的,这仅适用于大多数情况。如果您将该输出通过管道传输到文件dout,然后尝试使用相同的正则表达式,它将不起作用。

$ git diff dout | grep '^[+|-][^+|-]'
$

Anyways, hope that helps in your case

无论如何,希望对您的情况有所帮助

回答by wisbucky

This answer will retain the original red/green colors for readability. I provided a few variations in syntax:

此答案将保留原始红色/绿色以提高可读性。我提供了一些语法变化:

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

Explanation:

解释:

  • The git diff --coloris needed to prevent git from disabling the color when it is piping.
  • The grep --color=neveris to prevent grep removing the original color and highlighting the matched string.
  • We are matching for lines that start with red (\e[31m) or green (\e[32m) escape codes.
  • The $'...'(ANSI-C quoting syntax) or -P(perl syntax) is to let grepto interpret \eor \033as an ESCcharacter.
  • git diff --color需要,以防止混帐从禁用当管道的颜色。
  • grep --color=never是为了防止 grep 删除原始颜色并突出显示匹配的字符串。
  • 我们匹配以红色 ( \e[31m) 或绿色 ( \e[32m) 转义码开头的行。
  • $'...'(ANSI-C引用语法)或-P(perl的语法)是让grep解释\e\033作为ESC字符。

回答by Gabriel Staples

Here's another, simpler way to find only lines which have been modified, and hence begin with a single +or -, while retaining color output:

这是另一种更简单的方法来仅查找已修改的行,因此以单个+或开头-,同时保留颜色输出:

git diff -U0 --color=always HEAD~ | grep --color=never -E $'^\e\[(32m\+|31m-)'
  1. The -U0says to include 0 lines of context around the changed lines--ie: include just the changed lines themselves. See man git diff.
  2. The -Efor grep allows it to work with extended regular expressions
  3. The $''syntax apparently allows ANSI quoting, which properly interprets the ESC (escape, or 0x1b) character properly. See here.
  4. And here's the regex description from https://www.regex101.com: enter image description here
  5. Basically, ^matches the beginning of the line, \ematches the Escape char, which is the start of a color code in the terminal, \[matches the next char in the color code, which is [, and then the (this|that)syntax matches "this" or "that", where "this" is 32m+, which is a green + line, and 31m-is a red - line.
  6. Colors are like this: \e[32mis green and \e[31mis red.
  7. +shows lines marked by git diffas added, of course, and -shows lines marked by git diffas deleted.
  8. Note that --color=neveris requiredin the 2nd grepexpression in order to prevent it from highlighting its matches, which would otherwise screw up the color codes coming in from git diffto the left.
  9. The +has to be escaped too as \+because otherwise the +is a special regular expression (regex) character which specifies one or more occurrences of the preceding element. See here: https://en.wikipedia.org/wiki/Regular_expression#Basic_concepts.
  1. -U0说,包括0线改线周围背景的-即:只包括改变线本身。见man git diff
  2. -E对grep的允许工作与扩展正则表达式
  3. $''语法显然允许ANSI引述,其适当解释ESC(逃逸,或0x1b)字符正确。见这里
  4. 这是来自https://www.regex101.com的正则表达式描述:在此处输入图片说明
  5. 基本上,^匹配行首,\e匹配转义字符,即终端中颜色代码的开始,\[匹配颜色代码中的下一个字符,即[,然后(this|that)语法匹配“this”或“that” ,其中“this”是32m+,这是一条绿色的+线,31m-是一条红色的线。
  6. 颜色是这样的:\e[32m绿色和\e[31m红色。
  7. +通过标记显示线git diff为添加,当然,并-标记由显示线git diff为已删除。
  8. 请注意,--color=never需要在第二个grep表达式,以防止它突出其匹配,否则就会搞砸了在未来的色码git diff的左侧。
  9. The+也必须被转义,\+否则 the+是一个特殊的正则表达式(regex)字符,它指定一个或多个前面的元素出现。请参阅此处:https: //en.wikipedia.org/wiki/Regular_expression#Basic_concepts

References:

参考:

  1. https://git-scm.com/docs/git-diff#_combined_diff_format
  2. Answer by @user650654: Git diff to show only lines that have been modified
  3. Answer by @wisbucky: Git diff to show only lines that have been modified
  1. https://git-scm.com/docs/git-diff#_combined_diff_format
  2. @user650654 的回答:Git diff 仅显示已修改的行
  3. @wisbucky 的回答:Git diff 仅显示已修改的行

Related:

有关的:

  1. [my own answer] Git diff with line numbers (Git log with line numbers)
  2. [someone else's answer] Git diff with line numbers (Git log with line numbers)
  3. git diff with line numbers and proper code alignment/indentation
  4. git-filechange-search.sh- a script which allows you to search a file for a variable or function name and figure out which commitscontain changes with that variable or function name. Ex. usage: ./git-filechange-search.sh path/to/my/file.cpp variable_namewill find all commitswith changes to file.cpp that contain variable_namein them. This is useful to see where and when certain features were changed. It's as though it were a search that could observe sections of a file displayed via git blameover time.
  1. [我自己的答案] Git diff with line numbers(Git log with line numbers)
  2. [别人的回答] Git diff with line numbers(Git log with line numbers)
  3. 带有行号和正确代码对齐/缩进的 git diff
  4. git-filechange-search.sh- 一个脚本,它允许您在文件中搜索变量或函数名称,并找出哪些提交包含该变量或函数名称的更改。前任。用法:./git-filechange-search.sh path/to/my/file.cpp variable_name将查找包含其中包含对 file.cpp 的更改的所有提交variable_name。这有助于查看某些功能的更改位置和时间。就好像它是一种搜索,可以观察一段git blame时间内显示的文件部分。

回答by Gabriel Staples

How to use awkto show just the +and -lines, accounting for any color or text formatting git diffmay be outputting:

如何使用awk仅显示+-行,考虑任何颜色或文本格式git diff可能会输出:

Not a single one of the other answers here (including my other answer) will do exactly what you want 100% correctly. This answer, however, will. Here's a 1-liner you can copy and paste into your terminal. I've just made it multiple lines for readability--you can copy-paste it the same either way so I might as well make it readable!It relies on the awkprogramming language:

此处的其他答案(包括我的其他答案)中没有一个可以 100% 正确地完成您想要的操作。然而,这个答案会。这是一个 1-liner,您可以将其复制并粘贴到您的终端中。为了便于阅读,我刚刚将它分成了多行——你可以用任何一种方式复制粘贴它,这样我也可以让它可读!它依赖于awk编程语言:

git diff --color=always "$@" | awk '
# 1. Match and then skip "--- a/" and "+++ b/" lines
/^(3\[(([0-9]{1,2};?){1,10})m)?(--- a\/|\+\+\+ b\/)/ {
    next 
} 
# 2. Now print the remaining "+" and "-" lines ONLY! Note: doing step 1 above first was required or
# else those lines would have been matched by this matcher below too since they also begin with 
# the "+" and "-" symbols.
/^(3\[(([0-9]{1,2};?){1,10})m)?[-+]/ {
    print 
git diff --unified=0
} ' | less -RFX

Here are its features. All these features, when taken together, solve the shortcomings of every other answer here:

这是它的特点。所有这些功能结合在一起,解决了这里所有其他答案的缺点:

  1. It handles color AND no-color output. That's what this regular expression does: ^(\033\[(([0-9]{1,2};?){1,10})m)?
  2. It handles ALL COLORS and ALL TEXT FORMATTING OPTIONS, including bold, italics, strikethrough, etc, which you can set in your git configsettings. That's why the regex above has ;?and {1,10}in it: if it detects the start of a color or text formatting code, it will match up to 10 sequences of these combined ANSI codes.
  3. It does NOT also include lines which begin with @@and the word diff, as the accepted answerdoes. If you DO want those lines (which quite frankly, I think are useful :) ), do this instead:

    git diff -U0
    

    or

    git diff --unified=0
    
  4. It shows the output in the same exact way as git diffwould: in the lesspager with optional color output (-R), and only if the text is > 1 page (-F), and while retaining the current page of text on the screen when you quit (-X).

  1. 它处理颜色和无颜色输出。这就是这个正则表达式的作用:^(\033\[(([0-9]{1,2};?){1,10})m)?
  2. 它处理所有颜色和所有文本格式选项,包括粗体、斜体、删除线等,您可以git config设置中进行设置。这就是为什么上述正则表达式具有;?{1,10}它:如果它检测到的颜色或文本格式代码的开始,它将匹配到这些组合ANSI编码的10个序列。
  3. 它还不包括以@@和开头的行diff,就像接受的答案一样。如果您确实想要这些行(坦率地说,我认为它们很有用 :) ),请执行以下操作:

    git diff -U0
    

    或者

    ##代码##
  4. 它以完全相同的方式显示输出git diff:在less具有可选颜色输出 ( -R)的寻呼机中,并且仅当文本 > 1 页 ( -F) 时,同时在您使用q( -X)时在屏幕上保留当前文本页面.

It also has the benefit of being powerfuland easily configurable since it uses the awk programming language.

它还具有强大且易于配置的优点,因为它使用 awk 编程语言。

If you are interested in learning awk, here's some resources:

如果您有兴趣学习awk,这里有一些资源:

  1. gawk(GNU awk) manual: https://www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents
  2. Study git diffnand the comments therein: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/useful_scripts/git-diffn.sh
    1. If you want git diffntoo, which is git diffwith line numbers, see here: Git diff with line numbers (Git log with line numbers)
  3. Some awk "hello world" and syntax test examples: https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/tree/master/awk
  1. gawk(GNU awk) 手册:https: //www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents
  2. 研究git diffn和其中的评论:https: //github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/useful_scripts/git-diffn.sh
    1. 如果你也想要git diffn,这是git diff带有行号的,请参见此处:Git diff with line numbers (Git log with line numbers)
  3. 一些awk“hello world”和语法测试示例:https: //github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/tree/master/awk

As a bonus, I also wrapped up the above to be used as git diffc, which means "git diff to show ONLY 'c'hanges". Usage is identicalto git diff; just use git diffcinstead! It supports ALL options. Color is ON by default. To turn it off, simply use git diffc --no-coloror git diffc --color=never. See man git difffor details.

作为奖励,我还将上述内容打包用作git diffc,这意味着“git diff 仅显示 'c'hanges”。用法是相同git diff; 只需使用git diffc!它支持所有选项。默认情况下颜色为开。要关闭它,只需使用git diffc --no-colorgit diffc --color=never。详情请参阅man git diff

Since I just finished git diffn(a tool to show git diffwith line 'n'umbers) last night, writing git diffcwas trivial. I figured I better do it now while the knowledge is fresh in my head.

由于我昨晚刚刚完成git diffn(一个git diff用“数字”行显示的工具),所以写作git diffc是微不足道的。我想我最好现在就做,趁我脑子里的知识还很新鲜。

Install git diffc:

安装git diffc

Follow the instructions at the end of this answer here, except everywhere you see git-diffnin the instructions, use git-diffcinstead. That includes in the wgetcommand too. Downloading and installing git diffcis easy: it's just a few commands.

请按照此处答案末尾说明进行操作,除了您git-diffn在说明中看到的任何地方,请git-diffc改用。这也包括在wget命令中。下载和安装git diffc很简单:只需几个命令。