GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(config): match `~/` gitdir includes on Windows by b84330808 · Pull Request #2305 · gitpython-developers/GitPython

Conversation

@b84330808

@b84330808 b84330808 commented Oct 23, 2026

Copy link
Copy Markdown

On Windows, GitConfigParser never applies an [includeIf "gitdir:~/..."] section, while git config does.

os.path.expanduser returns the home directory with backslashes, so gitdir:~/work/ becomes C:\Users\me/work/**. GitPython compares gitdir patterns with git_dir written with forward slashes, and a backslash in a gitdir pattern escapes the next character, so the pattern never matches. Git converts the home directory to forward slashes when it expands ~ on Windows (interpolate_path() in path.c, used by prepare_include_condition_pattern() in config.c).

So with the usual setup

[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig-work

GitPython reads user.email etc. for a repository under ~/work from the global config only.

Repro on Windows, in a repository under the home directory whose .git/config includes a file that sets user.email = [email protected] through gitdir:~/<path to repo>/:

> git config --get user.email
[email protected]
> python -c "import git; print(git.Repo('.').config_reader('repository').get_value('user', 'email', 'NOT FOUND'))"
NOT FOUND

Change

On Windows, a pattern that is ~ or starts with ~/ gets the home directory with forward slashes. The rest of the pattern is unchanged, so backslashes written in the pattern are still escapes (test_conditional_includes_do_not_treat_backslashes_as_separators still passes). Other platforms and ~user patterns keep the previous os.path.expanduser call.

Tests

test_conditional_includes_expand_home_in_git_dir_pattern points the home directory at a temporary directory and checks that gitdir:~/target/ matches a repository below it. On Windows it fails without the change and passes with it; on other platforms it passes either way.

Validation

Run by the agent on Windows 11, Git for Windows 2.51.2, Python 3.11.9:

  • test/test_config.py: 55 passed, 3 skipped
  • ruff check, ruff format --check, mypy, basedpyright --warnings: no issues
  • full suite: same failures with and without the change, all from missing symlink privilege (WinError 1314) in test_submodule.py plus test/performance/test_commit.py
  • the repro above prints [email protected] after the change

This change and description were written by Claude Code (an AI agent) and opened through @b84330808's account.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@b84330808 @claude
fix(config): match ~/ gitdir includes on Windows
b83fcb8
On Windows, `GitConfigParser` never applied an
`[includeIf "gitdir:~/..."]` section, although `git config` does.
`os.path.expanduser` returns the home directory with backslashes, so
`gitdir:~/work/` became the pattern `C:\Users\me/work/**`. GitPython
compares gitdir patterns with the repository's `git_dir` written with
forward slashes, and in a gitdir pattern a backslash escapes the next
character instead of separating path components, so the pattern could
never match.

Git converts the home directory to forward slashes when it expands `~`
on Windows (`interpolate_path()` in `path.c`, which
`prepare_include_condition_pattern()` in `config.c` uses for gitdir
conditions). A usual setup such as

    [includeIf "gitdir:~/work/"]
        path = ~/.gitconfig-work

therefore made GitPython read `user.email` and other settings for a
repository under `~/work` from the global configuration only, while Git
read them from the included file.

On Windows, a pattern that is `~` or starts with `~/` now gets the home
directory with forward slashes. The rest of the pattern is unchanged, so
a backslash written in the pattern still escapes the next character, as
`test_conditional_includes_do_not_treat_backslashes_as_separators`
expects. Other platforms and `~user` patterns keep the previous
`os.path.expanduser` call.

`test_conditional_includes_expand_home_in_git_dir_pattern` points the
home directory at a temporary directory and checks that
`gitdir:~/target/` matches a repository below it. On Windows it fails
without this change and passes with it. On other platforms it passes
either way.

Validated on Windows 11 with Git for Windows 2.51.2 and Python 3.11.9:
`test/test_config.py` passes (55 passed, 3 skipped); `ruff check`,
`ruff format --check`, `mypy` and `basedpyright --warnings` report no
issues. For a repository whose `.git/config` includes a file through
`gitdir:~/...`, `git config --get user.email` returns the included value,
and `Repo.config_reader("repository").get_value("user", "email")` now
returns it too instead of finding no value.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Byron pushed a commit that referenced this pull request Oct 24, 2026
@codex
test(config): port home include and inline header regressions
ae03abd
Cover the configuration regressions from PRs #2305 and #2307 against actual
`git config` output. The current configuration facade already delegates
these operations to Git, so the valid cases pass without a runtime change.

Use scripted fixtures for a real home-relative conditional include and the
complete inline-header sample. Preserve native `HOME` and `USERPROFILE`
separators so the same test exercises the Windows path case on Windows.
Check both matching and nonmatching repositories and file/stream readers.
Also check adjacent headers, an escaped quote before `]`, and rejection of
unbalanced quotes, missing/stray brackets, malformed keys and sections.

Git accepts multiple section headers on one line but omits empty sections
from `git config list`. Reflect that output and the facade's documented
empty-section limitation instead of restoring a separate Python parser.
Document the existing `GIX-12` fallback without claiming native coverage.

Validation on macOS, Git 2.54.0, Python 3.12 and GixPython 0.2.0:

- All 11 added cases passed against the unchanged runtime.
- `test/test_config.py`: 62 passed with each of the CLI and Gix backends.
- `ruff check`, `ruff format --check`, `bash -n` and `git diff --check` passed.

Windows and Linux execution was not available for this local check.
Byron pushed a commit that referenced this pull request Oct 24, 2026
@codex @Byron
test(config): port home include and inline header regressions
37237cc
Cover the configuration regressions from PRs #2305 and #2307 against actual
`git config` output. The current configuration facade already delegates
these operations to Git, so the valid cases pass without a runtime change.

Use scripted fixtures for a real home-relative conditional include and the
complete inline-header sample. Preserve native `HOME` and `USERPROFILE`
separators so the same test exercises the Windows path case on Windows.
Check both matching and nonmatching repositories and file/stream readers.
Also check adjacent headers, an escaped quote before `]`, and rejection of
unbalanced quotes, missing/stray brackets, malformed keys and sections.

Git accepts multiple section headers on one line but omits empty sections
from `git config list`. Reflect that output and the facade's documented
empty-section limitation instead of restoring a separate Python parser.
Document the existing `GIX-12` fallback without claiming native coverage.

Validation on macOS, Git 2.54.0, Python 3.12 and GixPython 0.2.0:

- All 11 added cases passed against the unchanged runtime.
- `test/test_config.py`: 62 passed with each of the CLI and Gix backends.
- `ruff check`, `ruff format --check`, `bash -n` and `git diff --check` passed.

Windows and Linux execution was not available for this local check.
@Byron

Byron commented Oct 24, 2026

Copy link
Copy Markdown
Member

Codex, operating on behalf of Byron: This PR has been superseded by #2274. Its regression coverage has been integrated there, with assertions checked against Git’s behavior and fixes included where needed.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Byron Byron closed this Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@b84330808 @Byron
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.