How to use --color-words with git add --patch?

前端 未结 7 1789
梦谈多话
梦谈多话 2020-12-07 17:27

When diffing files, I prefer to use git diff --color-words. Is there a way to make this the default format for diffs when using git add --patch or

相关标签:
7条回答
  • 2020-12-07 18:00

    I recently solved this issue, but it requires modifying a Perl script in git. That's easy and requires no special skill, however.

    This solution requires that your git configuration use colorization for screen output, because that's the only circumstance under which git will show a word-based diff.

    1. Copy git-add--interactive from your installation to somewhere in your PATH environment variable and rename it git-add--interactive-words.
    2. Edit a line about half way down to change*
    @colored = run_cmd_pipe("git", @diff_cmd, qw(--color --), $path);
    

    to

    @colored = run_cmd_pipe("git", @diff_cmd, qw(--color --color-words --), $path);
    
    1. You can now run git add-interactive--words to do the equivalent of git add --interactive with colorized word-based diff.
    2. However, combining git add --patch with that is awkward because you need to pass the new script the right parameters. Fortunately, you can create an alias to the magic words in your .gitconfig:
    [alias]
    iaddpw = add--interactive-words --patch=stage --
    

    which means git iaddpw runs the equivalent of git add --interactive --patch with colorized word-based diff.


    *- For Git 2.18, this command is:

    my @display_cmd = ("git", @diff_cmd, qw(--color --), $path);
    
    0 讨论(0)
  • 2020-12-07 18:00

    As mentioned earlier adding diff-highlight to the interactive.diffFilter config key is the easiest option (since Git 2.9). The following comand does the trick on Debian/Ubuntu without copying scripts, changing permissions or mangling $PATH:

    git config interactive.diffFilter "perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight"
    

    Things like git -c interactive.diffFilter="git diff --color-words" add -p or git config interactive.diffFilter "git diff --color-words" don't work properly: add -p always keeps suggesting the first modified file.

    0 讨论(0)
  • 2020-12-07 18:09

    In your $(HOME)/.gitconfig file add this

    [color]
            diff = auto
            interactive = auto
    

    This should do.

    0 讨论(0)
  • 2020-12-07 18:11

    Solution

    Use diff-highlight | less -FRX --tabs=4 as your diffFilter:

    git -c interactive.diffFilter="diff-highlight | less -FRX --tabs=4" add --patch
    

    For more on diff-highlight: source, a quick primer

    Homebrew

    If you're using Homebrew (OS X), you can put the following in your .gitconfig (to use the already installed diff-highlight):

        [interactive]
            diffFilter = "$(git --exec-path | sed 's/libexec/share/')/contrib/diff-highlight/diff-highlight | less -FRX --tabs=4"
    

    1-1 correspondence between input and output

    As of git 2.17, the word diff solution must keep a 1-1 correspondence between input and output lines to avoid:

    $ git -c interactive.diffFilter="git diff --word-diff --color" add --patch
    fatal: mismatched output from interactive.diffFilter
    hint: Your filter must maintain a one-to-one correspondence
    hint: between its input and output lines.
    

    diff-so-fancy does not yet support this: https://github.com/so-fancy/diff-so-fancy/issues/35

    0 讨论(0)
  • 2020-12-07 18:15

    Taking cue from VonC's answer. Here are detailed steps to use --interactive option introduced in git 2.9.

    Add diff-highlight to your PATH.

    On Ubuntu, diff-highlight comes with git and can be found in /usr/share/git/diff-highlight/diff-highlight.

    Otherwise, you can download and set it up manually.

    cd ~/bin
    curl -LO "https://raw.githubusercontent.com/git/git/master/contrib/diff-highlight/diff-highlight"
    chmod u+x diff-highlight
    

    Restart your shell, if necessary.

    Then configure Git to filter your diffs whenever it's showing them in a pager:

    git config --global pager.log 'diff-highlight | less'
    git config --global pager.show 'diff-highlight | less'
    git config --global pager.diff 'diff-highlight | less'
    git config --global interactive.diffFilter diff-highlight
    

    This will put an extra emphasis on the changed part of a line, which is almost same as --word-diff.

    The advantage is you get word diff every where, like git log --patch or git add -p.

    0 讨论(0)
  • 2020-12-07 18:17

    With git 2.9 (June 2016), you will have a new option: interactive.diffFilter.

    See commit 0114384 (27 Feb 2016) by Jeff King (peff).
    (Merged by Junio C Hamano -- gitster -- in commit 2052c52, 03 Apr 2016)

    add --interactive: allow custom diff highlighting programs

    The patch hunk selector of add--interactive knows how ask git for colorized diffs, and correlate them with the uncolored diffs we apply. But there's not any way for somebody who uses a diff-filter tool like contrib's diff-highlight to see their normal highlighting.

    This patch lets users define an arbitrary shell command to pipe the colorized diff through. The exact output shouldn't matter (since we just show the result to humans) as long as it is line-compatible with the original diff (so that hunk-splitting can split the colorized version, too).

    You could then pipe that diff to a diff --color-words.

    As commented by Andrew Dufresne, the GitHub blog post refers to the contrib script contrib/diff-highlight:

    You can use "--color-words" to highlight only the changed portions of lines. However, this can often be hard to read for code, as it loses the line structure, and you end up with oddly formatted bits.

    Instead, this script post-processes the line-oriented diff, finds pairs of lines, and highlights the differing segments.

    The result puts an extra emphasis on the changed part of a line:

    Regarding those diffs, "diff-highlight" filter (in contrib/) learned to undertand "git log --graph" output better.

    See commit 4551fbb, commit 009a81e, commit fbcf99e, commit 7ce2f4c, commit e28ae50, commit 53ab9f0, commit 5013acc (21 Mar 2018) by Jeff King (peff).
    (Merged by Junio C Hamano -- gitster -- in commit d19e556, 10 Apr 2018)

    See more in "diff-highlight: detect --graph by indent"


    Note: before Git 2.17 (Q2 2018), The "interactive.diffFilter" used by "git add -i" must retain one-to-one correspondence between its input and output, but it was not enforced and caused end-user confusion.

    We now at least make sure the filtered result has the same number of lines as its input to detect a broken filter.

    See commit 42f7d45, commit af3570e (03 Mar 2018) by Jeff King (peff).
    (Merged by Junio C Hamano -- gitster -- in commit c5e2df0, 14 Mar 2018)

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