Skip to content

Allow relative config paths with includes#2169

Merged
Byron merged 1 commit into
mainfrom
fix-config-assert
Jul 12, 2026
Merged

Allow relative config paths with includes#2169
Byron merged 1 commit into
mainfrom
fix-config-assert

Conversation

@Byron

@Byron Byron commented Jul 12, 2026

Copy link
Copy Markdown
Member

Tasks

This section is for Byron only. Models continuing this PR must not add, remove, check, uncheck, rename, or reorder checkboxes here.

  • refackiew

Everything below this line was generated by GPT-5.

Created by Codex on behalf of Byron. Byron will review before this is ready to merge.

Summary

GitPython already supports relative include paths, but raised an AssertionError when the top-level configuration file was itself passed as a relative path. Normalize path-based parser inputs before reading so relative includes resolve against their containing config file and cycle detection uses consistent absolute paths.

Fixes #2103

Git behavior reference

This matches Git documentation and the relative and chained-relative include cases in t/t1305-config-include.sh.

Validation

  • uv run pytest -q test/test_config.py (31 passed, 1 skipped)
  • uv run pre-commit run --files git/config.py test/test_config.py
  • uv run mypy git/config.py
  • git diff --check
  • Full suite: 631 passed, 75 skipped, 34 unrelated environment failures due to uninitialized nested submodules and a missing legacy master branch

GitConfigParser asserted while resolving a relative include whenever the
top-level configuration file had itself been supplied as a relative path.
A regression test constructs that combination and verifies the included
value is available.

Normalize path-based inputs to absolute paths before reading them. This
lets relative includes resolve against the containing file and ensures
cycle detection uses the same canonical spelling for top-level and
included paths.

This matches Git's documented include behavior and the relative and
chained-relative coverage in t/t1305-config-include.sh.

Validation:
- uv run pytest -q test/test_config.py
- uv run pre-commit run --files git/config.py test/test_config.py
- uv run mypy git/config.py
- git diff --check
- full pytest: 631 passed, 75 skipped, 34 unrelated environment failures
  (uninitialized nested submodules and missing legacy master branch)
@Byron Byron marked this pull request as ready for review July 12, 2026 12:45
Copilot AI review requested due to automatic review settings July 12, 2026 12:45
@Byron Byron merged commit 3e59876 into main Jul 12, 2026
48 of 60 checks passed
@Byron

Byron commented Jul 12, 2026

Copy link
Copy Markdown
Member Author

Merged due to simplicity, without waiting for CI which basically doesn't finish today.

@Byron Byron deleted the fix-config-assert branch July 12, 2026 12:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

Normalize config parser input paths so relative includes resolve correctly when the top-level config file is provided as a relative path (avoiding assertion/cycle-detection inconsistencies).

Changes:

  • Normalize GitConfigParser.read() input file paths to absolute paths before processing includes.
  • Add a regression test covering relative top-level config path with a relative [include] path.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
test/test_config.py Adds coverage for relative config path + relative include behavior.
git/config.py Normalizes initial config paths to absolute to make include resolution and cycle detection consistent.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread git/config.py
files_to_read = list(self._file_or_files)
# END ensure we have a copy of the paths to handle

files_to_read = [osp.abspath(path) if isinstance(path, (str, os.PathLike)) else path for path in files_to_read]
Comment thread test/test_config.py
Comment on lines +313 to +325
@with_rw_directory
def test_config_relative_path_include(self, rw_dir):
included_path = osp.join(rw_dir, "included")
with GitConfigParser(included_path, read_only=False) as cw:
cw.set_value("included", "value", "included")

config_path = osp.join(rw_dir, "config")
with GitConfigParser(config_path, read_only=False) as cw:
cw.set_value("include", "path", "included")

relative_config_path = osp.relpath(config_path)
with GitConfigParser(relative_config_path, read_only=True) as cr:
assert cr.get_value("included", "value") == "included"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Relative path include in .gitconfig throws AssertionError

3 participants