Skip to content

config: read both home and xdg files for --global - #2196

Open
delilahw wants to merge 2 commits into
gitgitgadget:masterfrom
delilahw:lilah/fix-config-list-global-home-and-xdg/patchset
Open

delilahw wants to merge 2 commits into
gitgitgadget:masterfrom
delilahw:lilah/fix-config-list-global-home-and-xdg/patchset

Conversation

@delilahw

@delilahw delilahw commented Aug 7, 2026 •

Copy link
Copy Markdown

Hi,

Here is my reroll.

As reported in [1]: `$HOME/.gitconfig` and `$XDG_CONFIG_HOME/git/config` are both valid global config locations, but `git config list --global` only includes the former in its output.

Suppose we have this config in `$HOME/.gitconfig`:

[home]
    config = true

And this config in `$XDG_CONFIG_HOME/git/config`:

[xdg]
    config = true

Then, to reproduce the issue that `--global` only shows the home config:

$ git config list --global --show-scope --show-origin
global  file:/Users/delilah/.gitconfig    home.config=true

Git correctly applies the XDG config in its effective configuration, but it doesn't show up when `--global` is specified. We can confirm this by checking the output without the `--global` flag:

$ git config list --show-scope --show-origin
global  file:/Users/delilah/.config/git/config    xdg.config=true
global  file:/Users/delilah/.gitconfig            home.config=true

The expected behaviour is both configs should be shown when `--global` is specified, so we'd expect its output to look the same as above. This was confirmed in [2], which quoted the `git config` documentation:

> OPTIONS
>     --global::
>         For writing options: write to global `~/.gitconfig` file
>         rather than the repository `.git/config`, write to
>         `$XDG_CONFIG_HOME/git/config` file if this file exists and the
>         `~/.gitconfig` file doesn't.
>
>         For reading options: read only from global `~/.gitconfig` and from
>         `$XDG_CONFIG_HOME/git/config` rather than from all available files.

The first patch fixes forward slash normalisation on Windows paths. The second patch adds a flag for error handling when reading configuration files. The third patch implements the fix to include both config files when `--global` is specified.

Changes in v2:

  • Perform forward slash conversion in `xdg_config_home_for()` rather than the widely used `cleanup_path()`, which could've broken callers that do not expect normalized slashes.
  • Squash patches 2-4, such that implementation and tests are in the same patch rather than two sequential patches.
  • Reorder patches to prevent a regression from being intentionally introduced and then fixed in a later patch.
  • Refactor changes to `do_git_config_sequence()` (originally in v1 patch 4) to use a function for better readability.

[1]: https://lore.kernel.org/git/CAFA9we-QLQRzJdGMMCPatmfrk1oHeiUu9msMRXXk1MLE5HRxBQ@mail.gmail.com/
[2]: https://lore.kernel.org/git/xmqqmt5lezi3.fsf@gitster.g/
[3]: #1938

Thank you all for your time!
Delilah

cc: Delilah Ashley Wu delilahwu@microsoft.com
cc: Derrick Stolee stolee@gmail.com
cc: Johannes Schindelin johannes.schindelin@gmx.de
cc: Junio C Hamano gitster@pobox.com
cc: Patrick Steinhardt ps@pks.im
cc: Kristoffer Haugsbakk kristofferhaugsbakk@fastmail.com

@gitgitgadget

gitgitgadget Bot commented Aug 7, 2026

Copy link
Copy Markdown

There is an issue in commit 4c0da9e:
path: use forward slashes in XDG config on Windows

  • Commit not signed off

@delilahw

Copy link
Copy Markdown
Author

NB: i won't be submitting this via gitgitgadget anymore because I'd like the subject to contain v2 (superseding #1938). planning to use b4 instead.

@dscho

dscho commented Aug 13, 2026

Copy link
Copy Markdown
Member

NB: i won't be submitting this via gitgitgadget anymore because I'd like the subject to contain v2 (superseding #1938). planning to use b4 instead.

If you wanted to use GitGitGadget and have a v2, you would need to reopen the original PR and force-push there, then /submit there.

@delilahw

Copy link
Copy Markdown
Author

If you wanted to use GitGitGadget and have a v2, you would need to reopen the original PR and force-push there, then /submit there.

thanks for the suggestion @dscho !! i did something weird with my branch and it wouldn't let me reopen the original PR after force pushing, which is why i opened this new PR. but i've setup b4 in the meantime and keen to try it out hehe

@delilahw
delilahw force-pushed the lilah/fix-config-list-global-home-and-xdg/patchset branch 3 times, most recently from 33d79b9 to 1a89c55 Compare August 23, 2026 04:22
@gitgitgadget

gitgitgadget Bot commented Aug 23, 2026

Copy link
Copy Markdown

There is an issue in commit 4f4ffa4:
path: use forward slashes in XDG config on Windows

  • Lines in the body of the commit messages should be wrapped between 60 and 76 characters.
    Indented lines, and lines without whitespace, are exempt

@delilahw
delilahw force-pushed the lilah/fix-config-list-global-home-and-xdg/patchset branch 4 times, most recently from 9c9964c to dd42943 Compare August 23, 2026 09:53
@delilahw
delilahw force-pushed the lilah/fix-config-list-global-home-and-xdg/patchset branch from dd42943 to 6c6cc9c Compare September 2, 2026 13:20
@delilahw
delilahw force-pushed the lilah/fix-config-list-global-home-and-xdg/patchset branch 8 times, most recently from 6459e1d to a562361 Compare October 9, 2026 06:29
Record behaviour in two new tests: when no global configuration file
exists, `git config list` succeeds whereas `git config list --global`
fails. Only check the exit code, as we're not interested in the exact
error message.

This prevents regressions in the next patch, "config: read global scope
via config_sequence", which modifies `do_git_config_sequence()` to
optionally return a failure if no global configuration files were
successfully read (i.e. when the `--global` flag is specified).

Signed-off-by: Delilah Ashley Wu <delilahwu@microsoft.com>
When both `$HOME/.gitconfig` and `$XDG_CONFIG_HOME/git/config` exist,
`git config list --global` and `git config get --global` read the home
configuration file but ignore the XDG file. Bug reporters expected these
`--global` scoped commands to read both files [1][2], which would be
consistent with the documentation and the behaviour of the unscoped
variants. For example, `git config list` and `git config get` (without
`--global`) read from both files (in addition to system-wide and
repository-specific entries). We should address this inconsistency by
respecting both files during `--global` read operations.

The implementation assumes that each configuration scope corresponds to
a single file. So during `--global` read operations, Git selects one
file path to pass to `git_config_from_file_with_options(file)`. Because
the global scope can come from more than one file, we should use another
method to read the global configuration.

Since `git config list --show-scope --show-origin` reads both the home
and XDG files, there must be existing code that respects both locations,
namely `do_git_config_sequence()` which reads from all scopes. Introduce
an `ignore_system` flag and modify `git_config_system()` to respect it.
This makes `config_options` the primary way to disable parts of the
configuration sequence and allows callers of `do_git_config_sequence()`
to ignore all but the global scope (i.e. ignore system, local, worktree,
and cmdline). Reuse the function to read only the global scope when
`--global` is specified. This was the suggested solution [3] in the
original bug report [1].

The previous patch, "t1300: add tests for global config file existence",
recorded existing behaviour: when no global configuration file exists,
`git config list` should succeed whereas `git config list --global`
should fail. Since the configuration sequence gracefully ignores missing
global configuration files, track whether we successfully read at least
one of them and adjust the return code accordingly.

Keep populating `opts->source.file` in `builtin/config.c` as the
destination for write operations. Read operations use the configuration
sequence instead, which can be confusing. Add a comment to explain this
distinction.

Lastly, modify tests to check that both home and XDG configuration files
are respected during `--global` read operations.

[1] https://lore.kernel.org/git/CAFA9we-QLQRzJdGMMCPatmfrk1oHeiUu9msMRXXk1MLE5HRxBQ@mail.gmail.com/
[2] https://lore.kernel.org/git/CAAdFe9yhBk-WecVzCTsjQ-4Z3AZAbpP+w+B076ouM3qX6d1WAg@mail.gmail.com/
[3] https://lore.kernel.org/git/kl6ly1oze7wb.fsf@chooglen-macbookpro.roam.corp.google.com

Reported-by: Jade Lovelace <lists@jade.fyi>
Reported-by: Nils Fahldieck <nils@fahldieck.de>
Suggested-by: Glen Choo <glencbz@gmail.com>
Helped-by: Derrick Stolee <stolee@gmail.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Delilah Ashley Wu <delilahwu@microsoft.com>
@delilahw
delilahw force-pushed the lilah/fix-config-list-global-home-and-xdg/patchset branch from a562361 to 8b7c903 Compare October 9, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants