Git diff只显示已修改的行

时间:2013-09-15 08:55:30

标签: git

当我执行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中,我只对看到已修改的行感兴趣。

提前致谢。

7 个答案:

答案 0 :(得分:130)

你想要的是一个带有0行上下文的差异。您可以使用以下命令生成此内容:

git diff --unified=0

git diff -U0

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

git config diff.context 0

为全局设置任何存储库:

 git config --global diff.context 0

答案 1 :(得分:26)

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

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

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

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

注意:   - 如果您使用其他git差异选项,例如-R--src-prefix--dst-prefix--no-prefix,则需要修改上述解决方案。   - 两个greps可以组合成一个grep -E -v '^(\+\+\+ b/|--- a/|@@ |diff --git|index )',但我发现双grep版本更容易理解。

答案 2 :(得分:6)

跟进Chris的最新评论,后处理的主要问题是您希望保持以-|+开头的行,但您还想过滤掉以---|+++开头的行。另一方面,如果要将补丁文件存储在repo中(我会在Pydoop中),那么您希望保留以--|++开头的行,因此regexp会有所涉及:

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

正则表达式使用负向前瞻:请参阅Peter Boughton对this question的回答以获得详细解释。

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

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

答案 3 :(得分:2)

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

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

正则表达式表示该行应以+-开头,紧接着的字符不应该是那些。无论我是否逃过+,我都得到了相同的结果,顺便说一句......

示例:

$ cat testfile
A
B
C
D
E
F
G

说我将C更改为X,将E更改为Y,将G更改为Z

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

就像我上面所说的那样,这只适用于大多数情况。如果您将该输出传递给文件dout,然后尝试相同的正则表达式,它将无法正常工作。

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

无论如何,希望在你的情况下有所帮助

答案 4 :(得分:1)

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

这里没有一个其他答案(包括my other answer)可以完全正确地完成您想要的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

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

  1. 它处理彩色和无彩色输出。正则表达式就是这样的:^(\033\[(([0-9]{1,2};?){1,10})m)?
  2. 它处理所有颜色和所有文本格式选项,包括粗体,斜体,删除线等,您可以set in your git config settings。这就是为什么上面的正则表达式包含;?{1,10}的原因:如果它检测到颜色或文本格式代码的开始,它将最多与这些组合的ANSI代码的10个序列匹配。
  3. 它不像accepted answer那样包含以@@和单词diff开头的行。如果您确实想要这些行(坦率地说,我认为这是有用的:)),请改为:

    git diff --unified=0
    

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

由于它使用awk编程语言,因此还具有功能强大和易于配置的优点。

如果您有兴趣学习 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

作为奖励,我还包装了以上内容以用作git diffc,表示“ git diff仅显示'c'hanges”。用法与git diff 相同;只需使用git diffc即可!它支持所有选项。默认情况下,颜色为开。要关闭它,只需使用git diffc --no-colorgit diffc --color=never。有关详细信息,请参见man git diff

自从我昨晚刚完成git diffn(用{n'umbers行显示git diff的工具)以来,编写git diffc是微不足道的。我以为我现在最好在知识不新鲜的情况下这样做。

安装git diffc

遵循instructions at the end of this answer here,但在说明中看到git-diffn的所有地方除外,请改用git-diffc。这也包括在wget命令中。下载和安装git diffc很简单:只需几个命令。

答案 5 :(得分:0)

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

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解释为{ {1}}个字符。

答案 6 :(得分:0)

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

git diff -U0 --color=always HEAD~ | grep --color=never -E $'^\e\[(32m\+|31m-)'
  1. -U0表示要在已更改的行周围包含0条上下文-即:仅包含已更改的行本身。参见man git diff
  2. grep的-E允许它使用扩展的正则表达式
  3. $''语法显然允许使用ANSI引号,从而可以正确解释ESC(转义,或0x1b)字符。参见here
  4. 这是https://www.regex101.com中的正则表达式描述:enter image description here
  5. 基本上,^匹配行的开头,\e匹配转义字符,这是终端中颜色代码的开始,\[匹配行中的下一个字符颜色代码,即[,然后(this|that)语法匹配“ this”或“ that”,其中“ this”是32m+(绿色+线,{{ 1}}是一条红线。
  6. 颜色是这样的:31m-是绿色,\e[32m是红色。
  7. 当然,
  8. \e[31m显示添加了+的行,而git diff显示删除了带有-的行。
  9. 请注意,在第二个git diff表达式中,要求--color=never ,以防止突出显示其匹配项,否则将弄乱{ {1}}。
  10. grep也必须像git diff一样转义,因为否则+是一个特殊的正则表达式(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 to show only lines that have been modified
  3. @wisbucky的答案:Git diff to show only lines that have been modified

相关:

  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 with line numbers and proper code alignment/indentation
  4. git-filechange-search.sh-一个脚本,该脚本使您可以在文件中搜索变量或函数名称,并找出哪些 commits 包含该变量或函数名称的更改。例如用法:\+将查找所有对包含+的file.cpp进行更改的 commits 。这对于查看某些功能的更改时间和地点很有用。好像这是一次搜索,可以观察一段时间内通过./git-filechange-search.sh path/to/my/file.cpp variable_name显示的文件部分。