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): read an option on the same line as its section header by Keerthana-64 · Pull Request #2307 · gitpython-developers/GitPython

Conversation

@Keerthana-64

@Keerthana-64 Keerthana-64 commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

.gitmodules with an option on a section header line, git 2.54.0:

[submodule "lib"]
	path = lib
	url = https://good.example/lib
[submodule "lib"] url = https://evil.example/lib

$ git submodule init
Submodule 'lib' (https://evil.example/lib) registered for path 'lib'
>>> [(s.name, s.url) for s in git.Repo(".").submodules]
[('lib', 'https://good.example/lib')]

GitConfigParser._read matches headers with configparser's greedy \[(?P<header>.+)\] and drops the rest of the line, while git ends a header at its first unquoted ] and parses what follows as a normal config line. a tool that checks submodule URLs with GitPython therefore approves a different URL than the one git clones, and the same match turns [c] k = v ] into a section named c] k = v. the header now ends at the first unquoted ] and the remainder goes back through the parse loop as its own line, which matches git for options, comments and a second header ([f] [g] k = v sets g.k); a header with unbalanced quotes keeps the previous reading. test_option_after_section_header_is_read_like_git fails before and passes after, and the three full-suite failures on this machine (test_diff_with_staged_file, test_empty_repo, test_rebasing) fail the same way without the change.

Sorry, something went wrong.

Uh oh!

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

All reactions
@Keerthana-64
fix(config): read an option on the same line as its section header
5a86a1d
`GitConfigParser._read` recognized a section header with the inherited
`configparser` pattern `\[(?P<header>.+)\]`, matched against the
stripped line, and discarded everything after the match. git ends a
header at its first `]` outside a quoted subsection name and parses the
rest of the line as an ordinary config line, so `[core] bare = true`
sets `core.bare` in git and nothing in GitPython.

`.gitmodules` is read with this parser and is controlled by whoever
authored the superproject. For

    [submodule "lib"]
    	path = lib
    	url = https://good.example/lib
    [submodule "lib"] url = https://evil.example/lib

`git config -f .gitmodules --list` shows both URLs, and
`git submodule init` registers and later clones
`https://evil.example/lib`, while `Repo.submodules` reports
`https://good.example/lib`. A tool that uses GitPython to check which
URLs a repository's submodules point at approves a different URL than
the one git fetches. The greedy match also misread other lines:
`[c] k = v ]` became a section named `c] k = v` with no options, and
`[d] k = "multi\` continued on the next line produced an option named
`line"` instead of `d.k = multi  line`.

The header now ends at the first unquoted `]`, with backslash escapes
honored inside the quoted subsection name, and the text after it is fed
back through the parse loop as a line of its own. That reuses the
existing comment, option, continuation and header handling, so
`[e] ; comment` adds nothing, `[b]flag` is an implicit boolean, and
`[f] [g] k = v` sets `g.k`, all as git reads them. A header with
unbalanced quotes keeps the previous reading up to the last `]`, and
files whose headers stand alone on their lines parse exactly as before.

`test_option_after_section_header_is_read_like_git` in
`test/test_config.py` checks each case above against what
`git config -f <file> --list` prints on git 2.54.0. It fails before this
change and passes after. `ruff check`, `ruff format --check` and `mypy`
pass. In a full clone prepared with `init-tests-after-clone.sh`, the
pytest suite passes except `test_diff_with_staged_file`,
`test_empty_repo` and `test_rebasing`, which fail the same way without
this change.
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

@Keerthana-64 @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.