我可以让'git diff'只显示行号和更改的文件名?

这个问题需要“行号”。如果你不关心输出中的行号,请看这个问题和答案


基本上,我不希望看到更改的内容,只希望看到文件名和行号。

162810 次浏览

行号是指更改的行数还是实际包含更改的行号?如果你想要更改的行数,使用git diff --stat。这会给你一个像这样的显示:

[me@somehost:~/newsite:master]> git diff --stat
whatever/views/gallery.py |    8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)

没有选项可以获取更改本身的行号。

注意:如果你是已更改文件的只是在找名字 (没有为已更改行的行号),请参见另一个答案


这方面没有内置选项(我也不认为它有多大用处),但在Git中可以做到这一点,借助“外部差分”;脚本。

这是一个相当糟糕的问题;这将由您来修复输出您想要的方式。

#! /bin/sh
#
# run this with:
#    GIT_EXTERNAL_DIFF=<name of script> git diff ...
#
case $# in
1) "unmerged file $@, can't show you line numbers"; exit 1;;
7) ;;
*) echo "I don't know what to do, help!"; exit 1;;
esac


path=$1
old_file=$2
old_hex=$3
old_mode=$4
new_file=$5
new_hex=$6
new_mode=$7


printf '%s: ' $path
diff $old_file $new_file | grep -v '^[<>-]'

有关“外部差异”的详细信息,请参见Git手册GIT_EXTERNAL_DIFF的描述(大约在第700行,非常接近结尾)。

使用:

git diff --name-only

往前走!

在Windows上,这将过滤Git输出到文件和更改的行号:

(git diff -p --stat) | findstr "@@ --git"

diff --git a/dir1/dir2/file.cpp b/dir1/dir2/file.cpp
@@ -47,6 +47,7 @@ <some function name>
@@ -97,7 +98,7 @@ <another functon name>

要从中提取文件和更改的行需要更多的工作:

for /f "tokens=3,4* delims=-+ " %f in ('^(git diff -p --stat .^) ^| findstr ^"@@ --git^"') do @echo %f

a/dir1/dir2/file.cpp
47,7
98,7

最干净的输出,也就是文件名/路径

git diff-tree --no-commit-id --name-only -r

显示从现在到指定提交之间每个文件中更改的文件名和行数:

git diff --stat <commit-hash>

git version 2.17.1没有内置的标志上实现此目的。

下面是一个从统一的diff中过滤出文件名和行号的示例命令:

git diff --unified=0 | grep -Po '^diff --cc \K.*|^@@@( -[0-9]+,[0-9]+){2} \+\K[0-9]+(?=(,[0-9]+)? @@@)' | paste -s -d':'

例如,统一的差异:

$ git diff --unified=0
diff --cc foobar
index b436f31,df63c58..0000000
--- a/foobar
+++ b/foobar
@@@ -1,2 -1,2 +1,6 @@@ Line abov
++<<<<<<< HEAD
+bar
++=======
+ foo
++>>>>>>> Commit message

会导致:

❯ git diff --unified=0 | grep -Po '^diff --cc \K.*|^@@@( -[0-9]+,[0-9]+){2} \+\K[0-9]+(?=(,[0-9]+)? @@@)' | paste -s -d':'
foobar:1

查询普通grep匹配结果中命令的输出信息。

$ git diff --unified=0 | grep -Po '^diff --cc \K.*|^@@@( -[0-9]+,[0-9]+){2} \+\K[0-9]+(?=(,[0-9]+)? )| @@@.*' | sed -e '0~3{s/ @@@[ ]\?//}' | sed '2~3 s/$/\n1/g' | sed "N;N;N;s/\n/:/g"
foobar:1:1:Line abov
  1. grep -Po '^diff --cc \K.*|^@@@( -[0-9]+,[0-9]+){2} \+\K[0-9]+(?=(,[0-9]+)? ):匹配来自diff --cc <filename>的文件名或匹配来自@@@ <from-file-range> <from-file-range> <to-file-range>的行号或匹配@@@之后的剩余文本。
  2. sed -e '0~3{s/ @@@[ ]\?//}':从每第三行删除@@@[ ]\?,以获得在++<<<<<<< HEAD之前可选的1行上下文。
  3. sed '2~3 s/$/\n1/g':在列号的第2行和第3行之间每3行添加\n1
  4. sed "N;N;N;s/\n/:/g":用:连接每3行。

我最喜欢的:

git diff --name-status

前置文件状态,例如:

A   new_file.txt
M   modified_file.txt
D   deleted_file.txt

2)如果你想要统计,那么:

git diff --stat

将显示如下内容:

new_file.txt         |  50 +
modified_file.txt    | 100 +-
deleted_file         |  40 -

最后,如果你真的只想要文件名:

git diff --name-only

将简单地显示:

new_file.txt
modified_file.txt
deleted_file

使用:

git diff master --compact-summary

输出结果为:

 src/app/components/common/sidebar/toolbar/toolbar.component.html   |  2 +-
src/app/components/common/sidebar/toolbar/toolbar.component.scss   |  2 --

这正是你所需要的。与从远程进行提交或提取新提交时的格式相同。

PS:奇怪的是没有人这样回答。

我使用grep作为一个简单的解决方案。

$ git diff | grep -A2 -- '---'

输出示例:

--- a/fileA.txt
+++ b/fileA.txt
@@ -0,0 +1,132 @@
--
--- a/B/fileC.txt
+++ b/B/fileC.txt
@@ -33663,3 +33663,68800 @@ word_38077.png,Latin
--
--- a/D/fileE.txt
+++ b/D/fileE.txt
@@ -17998,3 +17998,84465 @@ word_23979.png,Latin
--
--- a/F
+++ b/F
@@ -1 +1 @@

也许你可以看到彩色的输出。它可以帮助您轻松地阅读输出。

试着使用:

git dif | grep -B <number of before lines to show> <regex>

在我的例子中,我试图搜索我在许多文件中放置调试语句的位置。我需要看看哪个文件已经得到了这样的调试语句:

git diff | grep -B 5 dd\(

它并不漂亮,但这里有一句bash:

git diff --unified=0 HEAD~1..HEAD | grep -Po '(^diff --git [a-zA-Z/._]*|^@@.*@@)' | while read l; do if [[ -n ${l##@@*} ]]; then f=${l#*/}; else echo "$f:${l##@@ }" | cut -d' ' -f1 | tr -d '-'; fi; done

解释:

  1. git diff --unified=0 HEAD~1..HEAD

从Git中检索提交信息

  1. grep -Po '(^diff --git [a-zA-Z/._]*|^@@.*@@)'

建立在先前的答案上,并过滤到包含 文件名和行号

  1. 为了提高可读性,将一行代码扩展为多行代码:
while read line; do
if [[ -n ${line##@@*} ]]; then
# Grabs filename from this pattern: "diff --git a/....."
filename=${line#*/};
else
# Grabs line number from this patterns: "@@ -<line> +<line> @@"
echo"$filename:${line##@@ }" | cut -d' ' -f1 | tr -d '-';
fi;
done

转换为预期输出的字符串解析:

file/name1.txt:34
file/name2.txt:98
file/name2.txt:101
file/name3.txt:2