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
Git diff to show only lines that have been modified
提问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. --color
is 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 C
to X
, E
to Y
, and G
to Z
.
说我的变化C
来X
,E
来Y
,并G
到Z
。
$ 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 --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 letgrep
to interpret\e
or\033
as anESC
character.
- 的
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-)'
- The
-U0
says to include 0 lines of context around the changed lines--ie: include just the changed lines themselves. Seeman git diff
. - The
-E
for grep allows it to work with extended regular expressions - The
$''
syntax apparently allows ANSI quoting, which properly interprets the ESC (escape, or 0x1b) character properly. See here. - And here's the regex description from https://www.regex101.com:
- Basically,
^
matches the beginning of the line,\e
matches 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" is32m+
, which is a green + line, and31m-
is a red - line. - Colors are like this:
\e[32m
is green and\e[31m
is red. +
shows lines marked bygit diff
as added, of course, and-
shows lines marked bygit diff
as deleted.- Note that
--color=never
is requiredin the 2ndgrep
expression in order to prevent it from highlighting its matches, which would otherwise screw up the color codes coming in fromgit diff
to the left. - 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.
- 该
-U0
说,包括0线改线周围背景的-即:只包括改变线本身。见man git diff
。 - 在
-E
对grep的允许工作与扩展正则表达式 - 的
$''
语法显然允许ANSI引述,其适当解释ESC(逃逸,或0x1b)字符正确。见这里。 - 这是来自https://www.regex101.com的正则表达式描述:
- 基本上,
^
匹配行首,\e
匹配转义字符,即终端中颜色代码的开始,\[
匹配颜色代码中的下一个字符,即[
,然后(this|that)
语法匹配“this”或“that” ,其中“this”是32m+
,这是一条绿色的+线,31m-
是一条红色的线。 - 颜色是这样的:
\e[32m
绿色和\e[31m
红色。 +
通过标记显示线git diff
为添加,当然,并-
标记由显示线git diff
为已删除。- 请注意,
--color=never
是需要在第二个grep
表达式,以防止它突出其匹配,否则就会搞砸了在未来的色码git diff
的左侧。 - The
+
也必须被转义,\+
否则 the+
是一个特殊的正则表达式(regex)字符,它指定一个或多个前面的元素出现。请参阅此处:https: //en.wikipedia.org/wiki/Regular_expression#Basic_concepts。
References:
参考:
- https://git-scm.com/docs/git-diff#_combined_diff_format
- Answer by @user650654: Git diff to show only lines that have been modified
- Answer by @wisbucky: Git diff to show only lines that have been modified
- https://git-scm.com/docs/git-diff#_combined_diff_format
- @user650654 的回答:Git diff 仅显示已修改的行
- @wisbucky 的回答:Git diff 仅显示已修改的行
Related:
有关的:
- [my own answer] Git diff with line numbers (Git log with line numbers)
- [someone else's answer] Git diff with line numbers (Git log with line numbers)
- git diff with line numbers and proper code alignment/indentation
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_name
will find all commitswith changes to file.cpp that containvariable_name
in 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 viagit blame
over time.
- [我自己的答案] Git diff with line numbers(Git log with line numbers)
- [别人的回答] Git diff with line numbers(Git log with line numbers)
- 带有行号和正确代码对齐/缩进的 git diff
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 awk
to show just the +
and -
lines, accounting for any color or text formatting git diff
may 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 awk
programming 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:
这是它的特点。所有这些功能结合在一起,解决了这里所有其他答案的缺点:
- It handles color AND no-color output. That's what this regular expression does:
^(\033\[(([0-9]{1,2};?){1,10})m)?
- It handles ALL COLORS and ALL TEXT FORMATTING OPTIONS, including bold, italics, strikethrough, etc, which you can set in your
git config
settings. 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. It does NOT also include lines which begin with
@@
and the worddiff
, 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
It shows the output in the same exact way as
git diff
would: in theless
pager 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 youq
uit (-X
).
- 它处理颜色和无颜色输出。这就是这个正则表达式的作用:
^(\033\[(([0-9]{1,2};?){1,10})m)?
- 它处理所有颜色和所有文本格式选项,包括粗体、斜体、删除线等,您可以在
git config
设置中进行设置。这就是为什么上述正则表达式具有;?
和{1,10}
它:如果它检测到的颜色或文本格式代码的开始,它将匹配到这些组合ANSI编码的10个序列。 它还不包括以
@@
和开头的行diff
,就像接受的答案一样。如果您确实想要这些行(坦率地说,我认为它们很有用 :) ),请执行以下操作:git diff -U0
或者
##代码##它以完全相同的方式显示输出
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,这里有一些资源:
gawk
(GNUawk
) manual: https://www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents- Study
git diffn
and the comments therein: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/useful_scripts/git-diffn.sh- If you want
git diffn
too, which isgit diff
with line numbers, see here: Git diff with line numbers (Git log with line numbers)
- If you want
- Some awk "hello world" and syntax test examples: https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/tree/master/awk
gawk
(GNUawk
) 手册:https: //www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents- 研究
git diffn
和其中的评论:https: //github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/useful_scripts/git-diffn.sh- 如果你也想要
git diffn
,这是git diff
带有行号的,请参见此处:Git diff with line numbers (Git log with line numbers)
- 如果你也想要
- 一些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 diffc
instead! It supports ALL options. Color is ON by default. To turn it off, simply use git diffc --no-color
or git diffc --color=never
. See man git diff
for details.
作为奖励,我还将上述内容打包用作git diffc
,这意味着“git diff 仅显示 'c'hanges”。用法是相同于git diff
; 只需使用git diffc
!它支持所有选项。默认情况下颜色为开。要关闭它,只需使用git diffc --no-color
或git diffc --color=never
。详情请参阅man git diff
。
Since I just finished git diffn
(a tool to show git diff
with line 'n'umbers) last night, writing git diffc
was 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-diffn
in the instructions, use git-diffc
instead. That includes in the wget
command too. Downloading and installing git diffc
is easy: it's just a few commands.
请按照此处答案末尾的说明进行操作,除了您git-diffn
在说明中看到的任何地方,请git-diffc
改用。这也包括在wget
命令中。下载和安装git diffc
很简单:只需几个命令。