`git config interactive.diffFilter diff-highlight`: the same diff by lines - and without color

1.4k Views Asked by At

After git config --global interactive.diffFilter diff-highlight my .gitconfig:

# This is Git's per-user configuration file.
[user]
    name = Vitaly Zdanevich
    email = [email protected]
[core]
    excludesfile = /Users/vitaly/.gitignore_global
[filter "lfs"]
    clean = git-lfs clean -- %f
    smudge = git-lfs smudge --skip -- %f
    process = git-lfs filter-process --skip
    required = true
[diff]
    tool = vimdiff
    context = 20
[difftool]
    prompt = false
[interactive]
    diffFilter = diff-highlight

But in git commit -p and git add -p I see the same diff line-by-line without color in default terminal.app:

git config interactive.diffFilter diff-highlight git diff without color

Also I tried:

git -c interactive.diffFilter="git diff --color-words" add -p

And get:

fatal: mismatched output from interactive.diffFilter
hint: Your filter must maintain a one-to-one correspondence
hint: between its input and output lines.

My git version is 2.17.2 (Apple Git-113) on macOS 10.14.1 from the official Command Line Tools, I prefer simplicity so not from the Brew.

2

There are 2 best solutions below

0
On BEST ANSWER

Looks like fixed with new git version (2.26.2)

git diff-highlight

0
On

Even though Git 2.26 helps, I would still recommend a more recent version of Git.

Those who use diff-so-fancy as the diff-filter noticed a regression or two in the code that parses the diff output in the built-in version of "add -p", which has been corrected with Git 2.38 (Q3 2022).

See commit 0a10167, commit fd3f7f6, commit b6633a0 (01 Sep 2022) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit fb094cb, 09 Sep 2022)

add -p: gracefully handle unparseable hunk headers in colored diffs

Reported-by: Philippe Blain
Helped-by: Phillip Wood
Signed-off-by: Johannes Schindelin

In this thread, Phillipe Blain reported that the built-in git add -p(man) command fails when asked to use diff-so-fancy to colorize the diff.

The reason is that this tool produces colored diffs with a hunk header that does not contain any parseable @@ ... @@ line range information, and therefore we cannot detect any part in that header that comes after the line range.

As proposed by Phillip Wood, let's take that for a clear indicator that we should show the hunk headers verbatim.
This is what the Perl version of the interactive add command did, too.

And:

add -p: ignore dirty submodules

Signed-off-by: Johannes Schindelin

Thanks to always running diff-index and diff-files with the --numstat option (the latter with --ignore-submodules=dirty) before even generating any real diff to parse, the Perl version of git add -p(man) simply ignored dirty submodules and does not even offer them up for staging.

However, the built-in variant did not use that flag because it tries to run only one diff command, skipping the unneeded diff-index/diff-files invocation of the Perl variant and therefore only faithfully recapitulates what the Perl code does once it does generate and parse the real diff.

This causes a problem when running the built-in add -p with diff-so-fancy because that diff colorizer always inserts an empty line before the diff header to ensure that it produces 4 lines as expected by git add -p (the equivalent of the non-colorized diff, index, --- and +++ lines).
But git diff-files(man) does not produce any index line for dirty submodules.

The underlying problem is not even the discrepancy in lines, but that git add -p presents diffs for dirty submodules: there is nothing that can be staged for those.

Let's fix that bug, and teach the built-in add -p to ignore dirty submodules, too.
This incidentally also fixes the diff-so-fancy problem ;-)