Git diff with line numbers (Git log with line numbers)

后端 未结 9 849
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-29 18:57

When I do a git diff or a git log -p, how do I get line numbers of the source file(s) inlined with the output?

I tried to look it up

相关标签:
9条回答
  • 2020-11-29 19:15

    You can try

    git blame
    

    on the file. It shows you the committer, commit id, and line number for each line in the file.

    0 讨论(0)
  • 2020-11-29 19:19

    Here is a script that attempts to fix this - not tested it in anger but it seems ok. It relies on the records git diff produces and uses awk to maintain line counts.

    # 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 
    
    0 讨论(0)
  • 2020-11-29 19:21

    Here's two more solutions, expanding on Andy Talkowski's code.

    Plain text:

      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}'
    

    Colored text, assuming \033[66m is the format for color codes:

      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}'
    

    The code changes lines that start with - and + to -1:- and +1:+, respectively, and lines that start with nothing to (5,6):. The numbers are the line numbers from the respective file.

    0 讨论(0)
  • 2020-11-29 19:28

    You can't get human-readable line numbers with git diff

    There aren't currently any options to get line-numbers displayed vertically on the side with git diff.

    Unified-diff format

    That information is available in the (c)hunk headers for each change in the diff though, it's just in unified-diff format:

    @@ -start,count +start,count @@
    

    The original state of the file is represented with -, and the new state is represented with + (they don't mean additions and deletions in the hunk header. start represents the starting line number of each version of the file, and count represents how many lines are included, starting from the start point.

    Example

    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
    

    The hunk header

    @@ -11,7 +11,7 @@
    

    says that the previous version of the file starts at line 11, and includes 7 lines:

    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
    

    while the next version of the file also starts at line 11, and also includes 7 lines.

    Unified-diff format isn't really for human consumption

    As you can probably tell, unified-diff format doesn't make it easy to figure out line numbers (at least if you're not a machine). If you really want line numbers that you can read, you'll need to use a diffing tool that will display them for you.

    Additional Reading

    • Official git-diff(1) Manual Page
    0 讨论(0)
  • 2020-11-29 19:29

    I like to use git difftool with meld as my difftool. It's easier to look at than git diff, has a nice side-by-side gui comparison, and shows line numbers on each side.

    Setup:

    1. Instructions on how to set up meld as your difftool for Windows or Linux

    Sample Screenshot:

    Update 24 May 2020:

    I just wrote git diffn over the last few days to be a drop-in replacement for git diff on the command-line. Give it a shot. See my other answer here.

    0 讨论(0)
  • 2020-11-29 19:31

    You can use git difftool to do the diff with an external editor that will display line numbers. Here's how to do it with vim / vimdiff:

    1. Set vimdiff as git's difftool:

      git config --global diff.tool vimdiff
      
    2. Configure ~/.vimrc to automatically show line numbers when using vimdiff:

      if &diff
          set number
      endif
      
    3. Run git difftool, which will use vimdiff with line numbers:

      git difftool
      
    0 讨论(0)
提交回复
热议问题