threads / discuss / 42318

'git diff-index' doesn't honor the 'diff.algorithm' variable

Subject: 'git diff-index' doesn't honor the 'diff.algorithm' variable

## tl;dr

5 messages between May 13, 2016 and May 15, 2016.

replies: 4people: 2as markdown or json

Dmitry Gutov· May 13, 2016, 23:45 UTC · lore
Hi all,

Subj. ...even though it's explicitly mentioned in the subcommand's man page. Git version 2.7.4 here.

To elaborate:
- Call 'git config --global diff.algorithm histogram'.
- Try the example from http://stackoverflow.com/a/36551123/615245.

'git diff test.css' gives the expected output using the non-default algorithm.

'git diff-index -p HEAD -- test.css' uses the default one.

Best regards, Dmitry.

Junio C Hamano· May 14, 2016, 18:40 UTC · re: Dmitry Gutov · lore

Re: 'git diff-index' doesn't honor the 'diff.algorithm' variable

Dmitry Gutov <dgutov@yandex.ru> writes:
Show 8 quoted lines
> Hi all,
>
> Subj. ...even though it's explicitly mentioned in the subcommand's man
> page. Git version 2.7.4 here.
>
> To elaborate:
>
> - Call 'git config --global diff.algorithm histogram'.

The variable belongs to UI config, meant for Porcelain "git diff", together with things like "diff.color", "diff.context", etc.

As the point of lower-level plumbing commands in the diff family, i.e. diff-files, diff-index and diff-tree, are about giving stable output, which are _not_ affected by random end-user configuration, for scripted use, it is very much deliberate design decision that they ignore the UI config variables.

A script that calls diff-index, if it wants to honor end-users' UI config variables, is allowed to use 'git config' to read them and turn them into appropriate command line options. e.g.

    algo=$(git config diff.algorithm)
    case "$algo" in
    minimal|histogram|patience) algo=--$algo ;;
    *) algo= ;;
    esac
    ...
    git diff-index $algo ... other args ...
or something like that.
Dmitry Gutov· May 15, 2016, 10:25 UTC · re: Junio C Hamano · lore

Re: 'git diff-index' doesn't honor the 'diff.algorithm' variable

Hi Junio,
On 05/14/2016 09:40 PM, Junio C Hamano wrote:
> The variable belongs to UI config, meant for Porcelain "git diff",
> together with things like "diff.color", "diff.context", etc.

OK, that makes sense. You might want to fix the man page, though, it says, like the 'git diff' one, "For instance, if you configured diff.algorithm variable to a non-default value and want to use the default one, then you have to use --diff-algorithm=default option.".

Show 14 quoted lines
> A script that calls diff-index, if it wants to honor end-users'
> UI config variables, is allowed to use 'git config' to read them and
> turn them into appropriate command line options.  e.g.
>
>     algo=$(git config diff.algorithm)
>     case "$algo" in
>     minimal|histogram|patience) algo=--$algo ;;
>     *) algo= ;;
>     esac
>
>     ...
>     git diff-index $algo ... other args ...
>
> or something like that.

Thanks, but we don't distribute any custom Git porcelains with Emacs. We usually can't rely on bash being available either. Doing an extra process call from Emacs for this niche a feature doesn't seem like a great idea either. To clarify, the problem is that `M-x vc-diff' doesn't honor the diff.algorithm option.

I'll have to see why we using 'git diff-index' there directly. Maybe we could switch to 'git diff'.

Junio C Hamano· May 15, 2016, 18:43 UTC · re: Dmitry Gutov · lore

Re: 'git diff-index' doesn't honor the 'diff.algorithm' variable

Dmitry Gutov <dgutov@yandex.ru> writes:
> OK, that makes sense. You might want to fix the man page, though, it
> says, like the 'git diff' one, "For instance, if you configured
> diff.algorithm variable to a non-default value and want to use the
> default one, then you have to use --diff-algorithm=default option.".

Thanks; I think the paragraph is shared among the "diff" family of commands both plumbing and Porcelain, so I'd say "patches welcome" at this point ;-).

> Thanks, but we don't distribute any custom Git porcelains with
> Emacs. We usually can't rely on bash being available either.

The script was an illustration of the logic--I am sure elisp is much core capable scripting environment than POSIX shell. Perhaps (setq vc-diff-git-diff-use-histogram t) in ~/.emacs is not too bad ;-)

> I'll have to see why we using 'git diff-index' there directly. Maybe
> we could switch to 'git diff'.
I do not think it is a good idea.

Depending on how much understanding vc-diff wants to have on what the diff output is saying, it may want to be read and parse parts of the output; an end user who has diff.color=always can easily ruin your day.

And no, running "git diff --color=never" is not a solution for that.

The Porcelain "git diff" command is not bound by any promise of stable output and reserves the right to change the default to better support human users. I think the upcoming version of Git turns the diff.renames setting on by default, for example. We might even add a side-by-side diff and make it the default someday. You do not want to be reading these "fancy" output, and you cannot keep updating the invocation of "git diff" by vc-diff with unbounded number options, e.g. --no-side-by-side, that will be added to defeat configuration variables that will be invented in the future.

Dmitry Gutov· May 15, 2016, 20:36 UTC · re: Junio C Hamano · lore

Re: 'git diff-index' doesn't honor the 'diff.algorithm' variable

On 05/15/2016 09:43 PM, Junio C Hamano wrote:
> I think the paragraph is shared among the "diff" family of
> commands both plumbing and Porcelain, so I'd say "patches welcome"
> at this point ;-).
I think I've done my part here. It's not like this is a feature request.
> The script was an illustration of the logic--I am sure elisp is much
> core capable scripting environment than POSIX shell.  Perhaps (setq
> vc-diff-git-diff-use-histogram t) in ~/.emacs is not too bad ;-)

Yes, doing it via a user option is already possible in Emacs. I was concerned that the user has to configure it twice (once for console, two for Emacs), but if you think it's fine, let's leave it at that.

Show 9 quoted lines
> The Porcelain "git diff" command is not bound by any promise of
> stable output and reserves the right to change the default to better
> support human users.  I think the upcoming version of Git turns the
> diff.renames setting on by default, for example.  We might even add
> a side-by-side diff and make it the default someday.  You do not
> want to be reading these "fancy" output, and you cannot keep
> updating the invocation of "git diff" by vc-diff with unbounded
> number options, e.g. --no-side-by-side, that will be added to defeat
> configuration variables that will be invented in the future.
Fair enough.

Thanks, Dmitry.

← back to recent threads