带行号的Git diff(带行号的Git日志)

Dre*_*eur 85 git line-numbers

当我执行a git diff或a时git log -p,如何获取与输出内联的源文件的行号?

我试着man git-diff | grep "line numbers"查一下,我试着谷歌搜索,但没有得到任何快速.

小智 80

你无法获得人类可读的行号 git diff

目前没有任何选项可以在侧面垂直显示行号git diff.

统一差异格式

对于diff中的每个更改,该信息在(c)hunk标题中可用,它只是以统一差异格式:

@@ -start,count +start,count @@
Run Code Online (Sandbox Code Playgroud)

文件的原始状态用-,用新的状态表示+(它们不代表hunk标题中的添加和删除.start表示文件每个版本的起始行号,count表示包含多少行,从起点开始.

diff --git a/osx/.gitconfig b/osx/.gitconfig
index 4fd8f04..fcd220c 100644
--- a/osx/.gitconfig
+++ b/osx/.gitconfig
@@ -11,7 +11,7 @@ <== HERE!
 [color "branch"]
        upstream = cyan
 [color "diff"]
-       meta = yellow
+       meta = cyan
        plain = white dim
        old = red bold
        new = green bold
Run Code Online (Sandbox Code Playgroud)

大块头

@@ -11,7 +11,7 @@
Run Code Online (Sandbox Code Playgroud)

说该文件的先前版本从第11行开始,包括7行:

11  [color "branch"]
12         upstream = cyan
13  [color "diff"]
14 -       meta = yellow
14 +       meta = cyan
15         plain = white dim
16         old = red bold
17         new = green bold
Run Code Online (Sandbox Code Playgroud)

该文件的下一个版本也从第11行开始,还包括7行.

统一差异格式并不适合人类消费

你可能会说,统一差异格式并不容易弄清楚行号(至少如果你不是机器).如果您真的想要可以读取的行号,则需要使用可以为您显示它们的衍生工具.

补充阅读

  • 这是一个grep,只提取修改后的文件中的行号,例如用于过滤checkstyle报告`git diff --unified = 0 | grep -Po'^\+\+\+ ./\K.*|^@@ - [0-9] +(,[0-9] +)?\ +\K [0-9] +(,[0-9] +)?(?= @@)'` (3认同)
  • 不过,只有当您指定“--unified=0”或“-U0”时,这才真正有用。 (2认同)

小智 18

这是另外两个解决方案,扩展了Andy Talkowski的代码.

纯文本:

  git diff | gawk 'match($0,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
   /^(---|\+\+\+|[^-+ ])/{print;next};\
   {line=substr($0,2)};\
   /^-/{print "-" left++ ":" line;next};\
   /^[+]/{print "+" right++ ":" line;next};\
   {print "(" left++ "," right++ "):"line}'
Run Code Online (Sandbox Code Playgroud)

彩色文本,假设\033[66m是颜色代码的格式:

  git diff --color=always | \
    gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
      match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
      bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
      {line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
      bare~/^-/{print "-"left++ ":" line;next};\
      bare~/^[+]/{print "+"right++ ":" line;next};\
      {print "("left++","right++"):"line;next}'
Run Code Online (Sandbox Code Playgroud)

代码更改这样开始的行-+-1:-+1:+与开始,线 to (5,6):.数字是相应文件中的行号.


Gab*_*les 11

自 2020 年 5 月 24 日起,您现在可以git diffn为此目的使用第三方工具(完全披露:我写的)。它是围绕 的轻量级包装器git diff,以awk基于模式/动作的编程语言编写。这是运行git diffn. 冒号 ( :) 全部保持白色是有意的,作为一个视觉队列,它们是从左到右的分隔符。(如果您不喜欢那样,在代码中很容易更改)。

在此处输入图片说明

1/3:是什么?

顶部git-diffn.sh

描述:

git-diffn.sh

  1. 一个插入式替换git diff也显示行'n'numbers!完全像 一样使用它git diff,除了您还会看到这些漂亮的行号以帮助您理解所做的更改。

  2. 因为它只是一个基于 awk 语言的轻量级包装器git diff,它接受所有接受的选项和参数git diff。例子:

  3. git diffn HEAD~

  4. git diffn HEAD~3..HEAD~2

  5. 适用于您的任何git diff颜色设置,即使您使用的是自定义颜色

  6. 请在此处查看我的答案,了解如何设置自定义差异颜色,以及查看自定义颜色输出的屏幕截图git diffn如何在 git diff 中自定义差异标头的颜色?

  7. 以下是git config我上面回答中的一些示例命令,用于设置自定义git diff颜色和属性(文本格式):

       git config --global color.diff.meta "blue"
       git config --global color.diff.old "black red strike"
       git config --global color.diff.new "black green italic"
       git config --global color.diff.context "yellow bold"
    
    Run Code Online (Sandbox Code Playgroud)
  8. in git diffn,颜色输出默认开启;如果要禁用输出颜色,则必须使用--no-color--color=never。详情请参阅man git diff。例子:

     git diffn --color=never HEAD~
     git diffn --no-color HEAD~3..HEAD~2
    
    Run Code Online (Sandbox Code Playgroud)

2/3:安装

  1. Windows(未经测试):这可能在Git for Windows附带的 bash 终端内工作,但未经测试。安装适用于 Windows 的 Git。打开它附带的 bash 终端,并尝试按照以下说明进行操作。我需要一些测试人员,他们将在 Git for Windows 中对此进行测试。请在此处查看并回答:https : //github.com/git-for-windows/git/issues/2635
  2. Mac(未经测试):使用终端并按照以下说明进行操作。您可能需要安装gawk. 如果是这样,试试这个brew install gawk
  3. Linux(在 Ubuntu 18.04 上测试并完美运行):按照下面的终端说明进行操作。

选项 1(我的建议):下载整个 repo,然后创建程序的符号链接,以便您可以通过执行以下操作轻松接收更新git pullrepo。

首先,cd到任何你想安装它的地方。然后运行:

git clone https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.git
cd eRCaGuy_dotfiles/useful_scripts
mkdir -p ~/bin
ln -si "${PWD}/git-diffn.sh" ~/bin/git-diffn
Run Code Online (Sandbox Code Playgroud)

完毕!现在只需执行下面的最后一步!

选项 2(对于那些只想要 1 个文件的人):一次只下载一个文件。

mkdir -p ~/bin
cd ~/bin
wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/useful_scripts/git-diffn.sh
chmod +x git-diffn.sh
mv git-diffn.sh git-diffn
Run Code Online (Sandbox Code Playgroud)

完毕!现在只需执行下面的最后一步!

最后一步:

现在关闭并重新打开您的终端,或者使用 重新获取它. ~/.bashrc,您就完成了!

git diffn现在将作为git diff!

这是一个演示:

3/3:演示git diffn

创建此文件:

hello_world.c:

#include <stdio.h>

int main()
{
    printf("Hello World\n");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

提交它:

git add hello_world.c
git commit -m "add hello_world.c"
Run Code Online (Sandbox Code Playgroud)

将其更改为此并保存文件:

hello_world.c:

// Basic hello world example

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello Gabriel\n");
    
    int i = 700;
    printf("i = %i\n", i);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在运行:

git diff
Run Code Online (Sandbox Code Playgroud)

这是git diff出于比较目的的first的输出:

$ git diff
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+// Basic hello world example
+
 #include <stdio.h>
 
-int main()
+int main(int argc, char *argv[])
 {
-    printf("Hello World\n");
-
+    printf("Hello Gabriel\n");
+    
+    int i = 700;
+    printf("i = %i\n", i);
     return 0;
-}
\ No newline at end of file
+}
Run Code Online (Sandbox Code Playgroud)

以及显示颜色的屏幕截图。请注意,红色突出显示的部分只是显示可以删除的空白空格(在这种情况下为空格):

在此处输入图片说明

现在这是git diffn. 请注意,它完美地显示了所有行号!

  • 已删除行的行号在左侧,并-在最左侧和最右侧显示一个符号,:以帮助您看得更清楚——无论您的眼睛是喜欢向下扫描到冒号的右侧还是向下扫描远处屏幕左侧。
  • 添加的行的行号更靠右,并+:.
  • 左侧(旧文件)和右侧(新文件)显示上下文中未更改行的行号,以,.分隔。

的输出git diffn

$ git diffn
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+        1:+// Basic hello world example
+        2:+
    1,   3: #include <stdio.h>
    2,   4: 
-   3     :-int main()
+        5:+int main(int argc, char *argv[])
    4,   6: {
-   5     :-    printf("Hello World\n");
-   6     :-
+        7:+    printf("Hello Gabriel\n");
+        8:+    
+        9:+    int i = 700;
+       10:+    printf("i = %i\n", i);
    7,  11:     return 0;
-   8     :-}
\ No newline at end of file
+       12:+}
Run Code Online (Sandbox Code Playgroud)

以及显示颜色的屏幕截图。请注意,冒号没有着色或样式化以匹配左侧和右侧的周围文本。这是有意和设计的行为,用作左侧添加的行号和git diff右侧的原始输出之间的视觉分隔符。

在此处输入图片说明

也可以看看

  1. 另请参阅我的其他答案here,我只建议您使用它meld作为git difftool替代。Meld很棒,我使用它的次数超过 waaaay git diffn,尽管我确实同时使用了两者。拥有git diffn可尽管如此,现在我几乎从来不使用git diff,除非我的另一台计算机上。

  • 很棒的文档,应该很详细。 (2认同)

wis*_*cky 7

一个快速的方法是使用git diff -U0. 这会将上下文行设置为 0,这将使 @@ 值与实际更改的行匹配。默认情况下,@@ 值包括 3 行 before/after 上下文,这对人类来说不方便。

例子:

git diff # default
@@ -10,8 +10,8 @@
Run Code Online (Sandbox Code Playgroud)

这很难计算更改行的行号,因为第 10 行指的是 before 上下文的第一行。第一个更改的行的实际行号为 10+3=13。要计算更改的行数,还必须减去前后上下文:8-3-3=2。

git diff -U0
@@ -13,2 +13,2 @@
Run Code Online (Sandbox Code Playgroud)

如您所见,设置 context = 0 使 @@ 值更易于人类阅读。可以看到更改的行从第 13 行开始,有 2 行更改。

这并不完美,因为它只显示每个块的行号。如果您想查看每一行的行号,请使用 difftool 作为外部编辑器。见/sf/answers/3503482671/


小智 6

这是一个试图解决这个问题的脚本 - 没有在愤怒中测试它,但似乎没问题.它依赖于git diff生成的记录,并使用awk来维护行数.

# Massage the @@ counts so they are usable
function prep1() {
   cat | awk -F',' 'BEGIN { convert = 0; }
       /^@@ / { convert=1; }
       /^/  { if ( convert == 1 ) { print $1,$2,$3;
              } else { print $0;
              }
              convert=0;
             }'
}

# Extract all new changes added with the line count
function prep2() {
  cat | awk 'BEGIN { display=0; line=0; left=0; out=1;}
     /^@@ / { out=0; inc=0; line=$4; line--; display=line; left=line;        }
     /^[-]/   { left++; display=left; inc=0; }
     /^[+]/   { line++; display=line; inc=0; }
     /^[-+][-+][-+] / { out=0; inc=0; }
     /^/    { 
               line += inc;
               left += inc;
               display += inc;
               if ( out == 1 ) {
                   print display,$0;
               } else {
                   print $0;
               }
               out = 1;
               inc = 1;
               display = line;
            }'
} 

git diff $1 | prep1 | prep2 
Run Code Online (Sandbox Code Playgroud)


wis*_*cky 6

您可以使用git difftool将显示行号的外部编辑器进行比较。以下是如何使用 vim / vimdiff 执行此操作:

  1. 将 vimdiff 设置为 git 的 difftool:

    git config --global diff.tool vimdiff
    
    Run Code Online (Sandbox Code Playgroud)
  2. 配置~/.vimrc为在使用 vimdiff 时自动显示行号:

    if &diff
        set number
    endif
    
    Run Code Online (Sandbox Code Playgroud)
  3. 运行 git difftool,它将使用带有行号的 vimdiff:

    git difftool
    
    Run Code Online (Sandbox Code Playgroud)


Gab*_*les 5

我喜欢使用git difftoolmeld作为我的difftool。它比 更容易查看git diff,有一个很好的并排 GUI 比较,并在每一侧显示行号。

设置:

  1. 关于如何将 meld 设置为 Windows或 Linux的 difftool 的说明

截图示例:

在此输入图像描述

2020 年 5 月 24 日更新:

我最近几天刚刚写了一篇文章,作为命令行的git diffn直接替代品。git diff试一试。请参阅我的其他答案