dandavison / delta

A syntax-highlighting pager for git, diff, grep, and blame output
https://dandavison.github.io/delta/
MIT License
22.54k stars 376 forks source link

🐛 Delta settings do not use .gitconfig set in GIT_CONFIG_GLOBAL env var #1113

Open tkf144 opened 2 years ago

tkf144 commented 2 years ago

Hi there,

I'm reluctantly creating this issue as I'm sure I'm just holding it wrong, but I just can't seem to activate the side-by-side feature from my .gitconfig. It works fine from CLI (-c core.pager=delta -c delta.side-by-side=true) and using env args (GIT_PAGER=delta DELTA_FEATURES=+side-by-side) but when using a minimal .gitconfig with the equivalent settings, I don't see the same results.

[core]
    pager = delta

[delta]
    side-by-side = true

image

I've created a small script while trying to figure this out; it's here: repo deleted - see below comment for script.

# Run test script with a clean environment; run.sh will add a few term vars back in
$ env -i ./run.sh
Current working directory:
    /home/tf/dev/repos/git_test
Version details:
    Git: git version 2.36.1
    Delta: delta 0.13.0

Initial state:
    'git config -l | grep include.path':

    Run verification aliases from both gitconfigs:
        git: 'testmain' is not a git command. See 'git --help'.
        git: 'testpager' is not a git command. See 'git --help'.
    'git config -l | grep delta':

    'git config -l':
        core.repositoryformatversion=0
        core.filemode=true
        core.bare=false
        core.logallrefupdates=true
    'printenv':
        COLORTERM=truecolor
        OLDPWD=/home/tf/dev/repos/git_test
        PWD=/home/tf/dev/repos/git_test
        SHLVL=0
        TERM=xterm-kitty
        TERMINAL=kitty
        TERMINFO=/usr/lib/kitty/terminfo
        _=/usr/bin/printenv

Run git diff using git CLI args:
diff --git a/sample_code.txt b/sample_code.txt
index cead32e..71b430f 100644
--- a/sample_code.txt
+++ b/sample_code.txt
@@ -3,3 +3,3 @@ B
 C
-D
+XXX
 E

State (CLI args):
    'git config -l | grep include.path':

    Run verification aliases from both gitconfigs:
        git: 'testmain' is not a git command. See 'git --help'.
        git: 'testpager' is not a git command. See 'git --help'.
    'git config -l | grep delta':

    'git config -l':
        core.repositoryformatversion=0
        core.filemode=true
        core.bare=false
        core.logallrefupdates=true
    'printenv':
        COLORTERM=truecolor
        OLDPWD=/home/tf/dev/repos/git_test
        PWD=/home/tf/dev/repos/git_test
        SHLVL=0
        TERM=xterm-kitty
        TERMINAL=kitty
        TERMINFO=/usr/lib/kitty/terminfo
        _=/usr/bin/printenv

Run git diff using GIT_PAGER=delta and DELTA_FEATURES=+side-by-side:
diff --git a/sample_code.txt b/sample_code.txt
index cead32e..71b430f 100644
--- a/sample_code.txt
+++ b/sample_code.txt
@@ -3,3 +3,3 @@ B
 C
-D
+XXX
 E

State (env args):
    'git config -l | grep include.path':

    Run verification aliases from both gitconfigs:
        git: 'testmain' is not a git command. See 'git --help'.
        git: 'testpager' is not a git command. See 'git --help'.
    'git config -l | grep delta':

    'git config -l':
        core.repositoryformatversion=0
        core.filemode=true
        core.bare=false
        core.logallrefupdates=true
    'printenv':
        COLORTERM=truecolor
        DELTA_FEATURES=+side-by-side
        GIT_PAGER=delta
        OLDPWD=/home/tf/dev/repos/git_test
        PWD=/home/tf/dev/repos/git_test
        SHLVL=0
        TERM=xterm-kitty
        TERMINAL=kitty
        TERMINFO=/usr/lib/kitty/terminfo
        _=/usr/bin/printenv

Run git diff using a single gitconfig (gitconfig_pager):
diff --git a/sample_code.txt b/sample_code.txt
index cead32e..71b430f 100644
--- a/sample_code.txt
+++ b/sample_code.txt
@@ -3,3 +3,3 @@ B
 C
-D
+XXX
 E

State (use gitconfig_pager alone):
    'git config -l | grep include.path':

    Run verification aliases from both gitconfigs:
        git: 'testmain' is not a git command. See 'git --help'.
        gitconfig_pager loaded
    'git config -l | grep delta':
        core.pager=delta
        delta.side-by-side=true
    'git config -l':
        alias.testpager=!echo gitconfig_pager loaded
        core.pager=delta
        delta.side-by-side=true
        core.repositoryformatversion=0
        core.filemode=true
        core.bare=false
        core.logallrefupdates=true
    'printenv':
        COLORTERM=truecolor
        GIT_CONFIG_GLOBAL=/home/tf/dev/repos/git_test/gitconfig_pager
        OLDPWD=/home/tf/dev/repos/git_test
        PWD=/home/tf/dev/repos/git_test
        SHLVL=0
        TERM=xterm-kitty
        TERMINAL=kitty
        TERMINFO=/usr/lib/kitty/terminfo
        _=/usr/bin/printenv

What have I missed? Thanks for taking a look.

dandavison commented 2 years ago

Hi @tkf144, sorry that's causing you problems, let's get to the bottom of this! It does work for me.

You may have already done this, but what does git config -l | grep delta show when you think you have side-by-side enabled/disabled in your gitconfig?

tkf144 commented 2 years ago

Thanks Dan. Appreciate your help.

My git config -l | grep delta doesn't seem suspicious; it shows delta being set as the pager and side-by-side being set true - output is below.

Here's the more minimal repro I'm now using. Run this in an empty dir using env --ignore-environment ./script.sh:

#!/usr/bin/env bash

# Suppress warning about terminal by providing this
export TERM=xterm-kitty

cd "$(dirname "$BASH_SOURCE")" || exit 1

cat <<GIT_CONFIG > ./gitconfig
[user]
    name = "Test Name"
    email = "TestEmail@gmail.com"

[core]
    pager = delta

[delta]
    side-by-side = true
GIT_CONFIG

export GIT_CONFIG_GLOBAL=gitconfig 

git init 1> /dev/null 2>&1

cat <<TEST_FILE > ./test_file.txt
A
B
C
TEST_FILE
git add ./test_file.txt 1> /dev/null 2>&1
git commit -m "Test commit" 1> /dev/null 2>&1

sed -i'' 's#B#X#g' ./test_file.txt

git diff -U1 ./test_file.txt

echo
echo "'git config -l | grep delta'"
git config -l | grep delta

unset GIT_CONFIG_GLOBAL
rm -rf ./.git ./test_file.txt ./gitconfig
diff --git a/test_file.txt b/test_file.txt
index b1e6722..9df4d5e 100644
--- a/test_file.txt
+++ b/test_file.txt
@@ -1,3 +1,3 @@
 A
-B
+X
 C

'git config -l | grep delta'
core.pager=delta
delta.side-by-side=true

image

dandavison commented 2 years ago

Hi @tkf144, your test script also doesn't cause delta to display in side-by-side mode for me.

However, when I copy your gitconfig from your test script into my usual gitconfig location, then it works: delta displays in side-by-side mode.

delta uses libgit2, via the git2 Rust bindings, to read git config. I am worried that perhaps this doesn't recognise the GIT_CONFIG_GLOBAL env var. So basically I'm worried that the way the test script is creating a sandboxed git repro environment might be confusing us: my suggestion of git config -l of course wasn't great either as it uses native git code to read git config, not libgit2.

Is it possible that there is something about the way you keep your real gitconfig on disk that, while it works for native git, does not work for libgit2 (and hence not for delta)?

Can you set delta settings other than side-by-side in your real gitconfig? I hope not!

tkf144 commented 2 years ago

Thanks @dandavison. That makes sense; looks like someone has previously raised this in https://github.com/libgit2/libgit2/issues/6182.

Can you set delta settings other than side-by-side in your real gitconfig? I hope not!

I double-checked and line-numbers had no effect either - delta is safe :)

Is it possible that there is something about the way you keep your real gitconfig on disk that, while it works for native git, does not work for libgit2 (and hence not for delta)?

There sure is. It relates to how I have my gitconfigs split up for different machines/envs and also topics, i.e. there are several 'partial' files. Exporting GIT_CONFIG_KEY_N+GIT_CONFIG_VALUE_N allows one to set Git config items (e.g. include.path), which is how I'm loading these due to use of variables (which gitconfig doesn't support, beyond $HOME). IIRC, GIT_CONFIG_{KEY,VALUE}_N are recent additions to Git, so if GIT_CONFIG_GLOBAL is not yet supported by libgit2, then the former is also unlikely to be.

Now that I know what's going on, I'm happy to work around it. Please feel free to do as you wish with this issue. Thanks for the great software Dan!

dandavison commented 2 years ago

OK, excellent, I'm glad we've got to the bottom of that. I think the title you've given this issue stands a good chance of helping others that encounter this problem so I'll close this as I don't think we have current delta development suggestions following from it. However, that's not to say that a mention in the manual that delta uses libgit2 to read config would hurt, especially if others run into similar problems.

ethanmsl commented 2 years ago

I'd like to suggest that this limitation of libgit2 be noted more clearly somewhere. (and this thread left as something other than closed, I think -- since it's a user-impacting issue that people might look for, even if it's an upstream issue that the delta team doesn't plan to directly address.)

I spent a fair bit of time looking through repo and manual and exploring setting options to find out what the problem was. In order to find this issue one has to establish that the cause is manually setting the GIT_CONFIG_(GLOBAL/SYSTEM) path variable. Only after ruling out a number of other issues that could cause the problem. (e.g. syntax issues, mis-installation issues, etc.)

And it's something that the people who collect their dotfiles for organizational and git'ing purposes probably have an interest in.

Pending a C-lang PR to fix the libgit2 issue a workaround is to pass the variables that would be set in toml as arguments to the pager variable itself. e.g.:

 [core]
    pager = delta --navigate --line-numbers --side-by-side

Since git, ofc, respects the GITCONFIG... path it can run pager correctly this way. (What differences may lurk between argument and toml set-up I couldn't say.)

dandavison commented 2 years ago

Hi @ethanmsl, thanks, I agree with your suggestions. I've updated the Configuration section in the manual, and added a new Environment variables section.

I also think that delta should have a delta doctor (or delta --doctor) command, and I've opened https://github.com/dandavison/delta/issues/1184 for that.