Git diff to show only lines that have been modified

前端 未结 7 1086
北恋
北恋 2020-12-04 08:10

When I do a git diff, it shows lines that have been added:

+ this line is added

lines that have been removed:

- this line i         


        
相关标签:
7条回答
  • 2020-12-04 08:48

    What you want is a diff with 0 lines of context. You can generate this with:

    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
    
    0 讨论(0)
  • 2020-12-04 08:51

    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 $'^\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'
    

    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 let grep to interpret \e or \033 as an ESC character.
    0 讨论(0)
  • 2020-12-04 08:52

    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:

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

    The regexp uses a negative lookahead: see Peter Boughton's answer to this question for a detailed explanation.

    If you do this often, you might want to set up a git alias for it:

    git config --global alias.diffonly '!git diff | grep -P "^\+(?:(?!\+\+))|^-(?:(?!--))"'
    
    0 讨论(0)
  • 2020-12-04 08:57

    Another hack (on un*x) to show just the lines beginning with + 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/

    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.

    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.
    0 讨论(0)
  • 2020-12-04 08:57

    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...


    Example:

    $ cat testfile
    A
    B
    C
    D
    E
    F
    G
    

    Say I change C to X, E to Y, and G to 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.

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

    Anyways, hope that helps in your case

    0 讨论(0)
  • 2020-12-04 09:01

    How to use awk to show just the + and - lines, accounting for any color or text formatting git diff may be outputting:

    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:

    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
    

    Here are its features. All these features, when taken together, solve the shortcomings of every other answer here:

    1. It handles color AND no-color output. That's what this regular expression does: ^(\033\[(([0-9]{1,2};?){1,10})m)?
    2. 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.
    3. It does NOT also include lines which begin with @@ and the word diff, as the accepted answer does. If you DO want those lines (which quite frankly, I think are useful :) ), do this instead:

      git diff --unified=0
      

      or

      git diff -U0
      
    4. It shows the output in the same exact way as git diff would: in the less 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 you quit (-X).

    It also has the benefit of being powerful and easily configurable since it uses the awk programming language.

    If you are interested in learning awk, here's some resources:

    1. gawk (GNU awk) manual: https://www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents
    2. Study git diffn and the comments therein: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/useful_scripts/git-diffn.sh
      1. If you want git diffn too, which is git diff with line numbers, see here: Git diff with line numbers (Git log with line numbers)
    3. Some awk "hello world" and syntax test examples: 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 identical to 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.

    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.

    Install 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.

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