Search code examples
gitconfig

git config option not being overriden in an `includeIf` config file


I want to use two git "profiles" on my machine: work & personal. I've done this successfully for years using the includeIf directive in my global .gitconfig file.

# ~/.gitconfig
[user]
    name = John Doe
    email = johndoe@example.com
[includeIf "gitdir:/home/jdoe/dev/workstuff"]
    path = ~/dev/workstuff/.gitconfig


# ~/dev/workstuff/.gitconfig
[user]
    name = Jonathan Doe
    email = j.doe@company.com

And if I check the config in the respective repos, I get the corresponding values as expected.

[~/dev/personal/app] $ git config --get user.name
John Doe
[~/dev/personal/app] $ git config --get user.email
johndoe@example.com

[~/dev/workstuff/project/] $ git config --get user.name
Jonathan Doe
[~/dev/workstuff/project/] $ git config --get user.email
j.doe@company.com

Recently I have begun signing my git commits using my SSH key. However, I only need to do this for my work repos. So I added the following config to each file:

# ~/.gitconfig
[gpg]
    format = ssh
[commit]
    gpgsign = false


# ~/dev/workstuff/.gitconfig
[user]
    name = Jonathan Doe
    email = j.doe@company.com
    signingkey= ~/.ssh/my_signing_key.pub
[gpg "ssh"]
    allowedSignersFile = ~/dev/workstuff/.git-allowed-signers
[commit]
    gpgsign = true

However, the gpgsign directive in the work config file refuses to override the global setting, even though every other directive does.

[~/dev/personal/app] $ git config --get user.signingkey
             # blank value, which is correct because I didn't set a global signing key
[~/dev/personal/app] $ git config --get commit.gpgsign
false        # correct

[~/dev/workstuff/project/] $ git config --get user.signingkey
~/.ssh/my_signing_key.pub
[~/dev/workstuff/project/] $ git config --get gpg.ssh.allowedSignersFile
~/dev/workstuff/.git-allowed-signers
[~/dev/workstuff/project/] $ git config --get commit.gpgsign
false        # 🤬🤬🤬

Am I doing something wrong? Is it a known bug? Note that I have seen both gpgsign (lowercase) and gpgSign (camelCase) used in different resources and tutorials. I have tried both ways, but neither way overrides correctly.

Using git 2.43.2 in Ubuntu 22.04.


Solution

  • Git parses config settings in a specific order, and when duplicate settings are found, the last one wins:

    The files are read in the order given above, with last value found taking precedence over values read earlier.

    Presumably what's happening in your case is that your additional included config is getting overridden by other settings that are read after it. Perhaps your global config looks like this:

    # ...
    
    [user]
        name = John Doe
        email = johndoe@example.com
    [includeIf "gitdir:/home/jdoe/dev/workstuff"]
        path = ~/dev/workstuff/.gitconfig # this sets gpgsign to true
    
    # ...
    
    [commit]
        gpgsign = false # this sets gpgsign back to false
    

    If you simply move the includeIf line to the bottom of your global config, it will set those values last and they will be the final values.