173

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

+ this line is added

已删除的行:

- this line is removed

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

this line is not modified
this line is also not modified

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

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

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

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

4

7 回答 7

238

你想要的是一个 0 行上下文的差异。您可以使用以下方法生成它:

git diff --unified=0

或者

git diff -U0

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

git config diff.context 0

要将其设置为全局,对于任何存储库:

 git config --global diff.context 0
于 2013-09-15T09:02:30.100 回答
53

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

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

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

  • git diff -U0: 选择 0 个上下文行
  • 第一个 grep 仅包括以+or开头的所有行-
  • --- a/第二个 grep 排除以or开头的行+++ b/

颜色

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

git diff -U0 --color | grep '^\e\[[^m]*m[-+]' | grep -Ev '(--- a/|\+\+\+ b/)'
  • 表达式 ,^\e\[[^m]*m[-+]查找行首 ( ^),然后是转义字符 ( \e),其后[一起开始转义序列,然后是任何不是“m”的字符(数字、分号或什么都没有),然后是“ m" 结束转义序列。
  • 请注意,以下所有都是有效的转义序列:\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 + stroke out), \e[1;4;9;31m(bold +下划线+删除线+红色)。默认的 git 颜色使用红色和绿色,但可以重新配置。
  • --color是一样的--color=always
  • --- a/+++ b/出现在行首的限制已被删除,以适应转义序列,这可能导致边缘情况。

补充说明:

  • -R如果您使用额外的 git diff 选项,例如, --src-prefix, --dst-prefix,--no-prefix等,则需要修改上述解决方案。
  • 两个 grep 可以组合成一个grep -E -v '^(\+\+\+ b/|--- a/|@@ |diff --git|index )',但我发现双 grep 版本更容易理解。
于 2014-10-29T03:21:03.043 回答
8

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

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

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


例子:

$ cat testfile
A
B
C
D
E
F
G

假设我更改CX、和。EYGZ

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

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

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

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

于 2017-12-07T19:18:53.700 回答
6

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

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

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

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

git config --global alias.diffonly '!git diff | grep -P "^\+(?:(?!\+\+))|^-(?:(?!--))"'
于 2014-01-17T10:32:55.950 回答
4

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 $'^\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'

Explanation:

  • The git diff --color is needed to prevent git from disabling the color when it is piping.
  • The grep --color=never is 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 grep to interpret \e or \033 as an ESC character.
于 2019-08-20T17:49:31.887 回答
1

我可以要求 git 只显示已修改的行并忽略所有其他未修改的代码吗?

并且来自主要答案下的OP的后续评论

感谢您的快速回复。这解决了我的一半问题,但我仍然得到一些行,例如@@ -1 +1 @@在我的 diff 和顶部的 git diff have 中diff --git a/db/xxxxxxx b/db/xxxx index xxxxx..aaaaaaa bbbbbbbb。-r3b00t

git-diffc.sh awk为了解决上述两个请求,这里是使用我写的基于-language 的包装器的 1 行解决方案git diff

git diffc

完毕!

以下是 的特点git diffc
所有这些功能结合在一起,可以解决这里所有其他答案的缺点:

  1. 它处理彩色和非彩色输出。这就是这个正则表达式的作用:^(\033\[(([0-9]{1,2};?){1,10})m)?
  2. 它处理所有颜色和所有文本格式选项,包括粗体、斜体、删除线等,您可以在设置中进行git config设置。这就是上面的正则表达式包含;?{1,10}在其中的原因:如果它检测到颜色或文本格式代码的开头,它将匹配多达 10 个这些组合 ANSI 代码的序列。
  3. 它不包括以@@和单词开头的行diff,就像公认的答案一样。如果您确实想要这些行(坦率地说,我认为它们很有用:)),请改为:
    git diff --unified=0
    
    或者
    git diff -U0
    
  4. 它以与以下方式完全相同的方式显示输出git diff:在less具有可选颜色输出的寻呼机-R中(.-Fq-X

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

的样本输出git diff 8d4d4fd3b60f200cbbb87f2b352fb097792180b2~2..8d4d4fd3b60f200cbbb87f2b352fb097792180b2~3

diff --git a/useful_scripts/rg_replace.sh b/useful_scripts/rg_replace.sh
index 74bc5bb..0add69d 100755
--- a/useful_scripts/rg_replace.sh
+++ b/useful_scripts/rg_replace.sh
@@ -2,12 +2,11 @@
 
 # This file is part of eRCaGuy_dotfiles: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles
 
-# STATUS: functional and ready-to-use
-
+# WORK IN PROGRESS! <===========
 # This is a simple wrapper around RipGrep (`rg`) to allow in-place find-and-replace, since the
 # `rg --replace` option replaces only the stdout, NOT the contents of the file.
 # `man rg` under the `--replace` section states: "Neither this flag nor any other ripgrep
-# flag will modify your files." This wrapper overcomes that limitation.
+# flag will modify your files."
 
 # INSTALLATION INSTRUCTIONS:
 # 1. Install RipGrep: https://github.com/BurntSushi/ripgrep#installation

与 的样本输出相比git diffc 8d4d4fd3b60f200cbbb87f2b352fb097792180b2~2..8d4d4fd3b60f200cbbb87f2b352fb097792180b2~3。请注意,仅显示-+行,而周围的上下文行消失了,所有其他行(例如diff, index, ---,+++@@)也消失了!:

-# STATUS: functional and ready-to-use
-
+# WORK IN PROGRESS! <===========
-# flag will modify your files." This wrapper overcomes that limitation.
+# flag will modify your files."

git diffc代表“git diff c hanges”,意思是:只显示更改的代码行,没有别的。我写的。它不是常规 git 的一部分。

它支持 . 支持的所有选项和参数git diff,因为它只是git diff.

在此处下载:git-diffc.sh。它是我的eRCaGuy_dotfiles 存储库的一部分。

要安装它:

git clone https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.git
cd eRCaGuy_dotfiles/useful_scripts
mkdir -p ~/bin
ln -si "${PWD}/git-diffc.sh" ~/bin/git-diffc

如果这是您第一次创建或使用该目录,现在手动注销并重新登录~/bin,以便将 Ubuntu 的默认~/.profile文件添加~/bin到您的PATH变量中。如果注销并重新登录不起作用,请将以下几行代码添加到您的~/.profile文件中,然后注销 Ubuntu 并重新登录:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

而已!

用法:git diff。前任:

git diffc
git diffc -h
git diffc commit1 commit2
git diffc --no-color
# etc.

附加安装说明:

另请参阅我的其他答案的安装部分,git diffn我也在这里写过git-diffn除了在这些说明中看到的任何地方,请git-diffc改用。这也包括在wget命令内部。下载和安装git diffc很容易:只需几个命令。

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

下面的代码构成了git diffc包装器。

这里没有一个其他答案(包括我的其他答案)会完全正确地做你想要的 100%。然而,这个答案会。这是一个 1-liner,您可以将其复制并粘贴到您的终端中。为了便于阅读,我刚刚将它设置为多行——你可以用同样的方式复制粘贴它,所以我不妨让它可读!它依赖于awk编程语言:

git diff --color=always "$@" | awk '
# 1. Match and then skip "--- a/" and "+++ b/" lines
/^(\033\[(([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.
/^(\033\[(([0-9]{1,2};?){1,10})m)?[-+]/ {
    print $0 
}
' | less -RFX

如果您有兴趣学习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
  3. 如果你也想git diffngit diff行号,请看这里:Git diff with line numbers(Git log with line numbers)
  4. 一些 awk “hello world”和语法测试示例:https ://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/tree/master/awk

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

因为我昨晚刚刚完成git diffn(一个git diff用“数字”行显示的工具),所以写作git diffc是微不足道的。我想我最好现在就在我脑海中浮现知识的时候去做。

于 2020-05-25T19:53:01.267 回答
0

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

git diff -U0 --color=always HEAD~ | grep --color=never -E $'^\e\[(32m\+|31m-)'
  1. 说在更改的-U0行周围包含 0 行上下文 - 即:仅包含更改的行本身。见man git diff
  2. -Efor grep 允许它使用扩展的正则表达式
  3. $''语法显然允许 ANSI 引用,它可以正确解释 ESC(转义或 0x1b)字符。见这里
  4. 这是来自https://www.regex101.com的正则表达式描述:在此处输入图像描述
  5. 基本上,^匹配行的开头,\e匹配 Escape 字符,它是终端中颜色代码的开始,\[匹配颜色代码中的下一个字符,即[,然后(this|that)语法匹配“this”或“that” ,其中“this”是32m+,它是一条绿色的 + 线,31m-是一条红线。
  6. 颜色是这样的:\e[32m是绿色的,\e[31m是红色的。
  7. +当然,显示标记为已添加的行git diff,并-显示标记git diff为已删除的行。
  8. 请注意,第二个表达式--color=nevergrep要这样做,以防止它突出显示其匹配项,否则会破坏从git diff左侧进入的颜色代码。
  9. +也必须转义,因为\+否则+是一个特殊的正则表达式 (regex) 字符,它指定前面元素的一次或多次出现。见这里:https ://en.wikipedia.org/wiki/Regular_expression#Basic_concepts 。

参考:

  1. https://git-scm.com/docs/git-diff#_combined_diff_format
  2. @user650654 回答:Git diff 仅显示已修改的行
  3. @wisbucky 回答:Git diff 仅显示已修改的行

有关的:

  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随着时间的推移显示的文件部分。
于 2020-05-21T08:00:13.800 回答