Skip to content

BREAKING CHANGES for v4.0#2177

Draft
Byron wants to merge 1 commit into
mainfrom
v4-breaking
Draft

BREAKING CHANGES for v4.0#2177
Byron wants to merge 1 commit into
mainfrom
v4-breaking

Conversation

@Byron

@Byron Byron commented Jul 20, 2026

Copy link
Copy Markdown
Member

In order to make progress, at some point there should be a mildly breaking release.
For now not much is planned, except that it's worth a try.

The alternative is to see if what's planned as V4 can work for V3 users out of the box.

Changes

  • a native python and conformant git config implementation. Breaking because it's won't need workarounds.
  • fix __del__ and make object destruction deterministic again (maybe exceptions keep objects alive)
  • Git class facade that avoids dynamic calls in favor of statically defined and documented ones.

Other possibilities, maybe not breaking

  • discovery of dynamic methods and code-intelligence, as extracted from docs, for basedpyright and mypi maybe.

@Byron Byron added this to the v4.0 milestone Jul 20, 2026
Previously it was based on an ini-parser, which depends on the
Python version and also isn't actually dealing with the Git's
specific grammar and rules.

Now it's much more consistent, albeit probably also slower.

--- agent

Replace the line-oriented INI parsing logic in GitConfigParser with a
character-stream parser modeled on Git's config.c implementation.

The inherited configparser section matcher treats everything between the
first opening bracket and the last closing bracket as one section name.
Consequently, GitPython interpreted a header such as:

    [user] [other]

as one section named "user] [other", while Git interpreted it as two
successive section headers and assigned following values to "other".
Writing opaque section names through the INI serializer could therefore
change the configuration's meaning when Git subsequently read it.

Implement Git's configuration grammar directly, following the behavior of
git_parse_source(), get_base_var(), get_value(), and parse_value(). The new
parser handles:

- basic and quoted-subsection section headers
- multiple section headers in the same character stream
- comments introduced by '#' or ';'
- quoted and unquoted values
- supported backslash escapes
- backslash-newline continuations
- leading and trailing whitespace rules
- CRLF input and UTF-8 byte-order marks
- entries without values, represented semantically as boolean true
- duplicate options while preserving their order

Reject syntax that Git itself rejects, including colon delimiters,
underscore-containing option names, malformed section headers, unknown
value escapes, and unterminated quoted values.

Replace the raw value writer with a canonical Git-config serializer.
Values are always quoted, with backslashes, quotes, newlines, tabs, and
backspaces escaped. Quoted subsection names are parsed and re-escaped
canonically before being written. Comments and original whitespace remain
intentionally unpreserved when a dirty configuration is flushed.

Validate section names by parsing them as complete Git section headers.
This ensures each supplied name identifies exactly one section and
prevents unquoted closing brackets from injecting another section.
Validate option names against Git's ASCII letter, digit, and hyphen
grammar as well.

Update fixtures that previously depended on INI syntax rejected by Git,
and adjust expectations for decoded value escapes and valueless boolean
entries.

Add coverage for:

- the differing interpretation of adjacent section headers
- BOM, CRLF, comments, continuations, and valueless entries
- malformed syntax rejected by Git
- canonical value serialization and reparsing
- real `git config` interoperability
- closing brackets inside quoted subsection names
- quotes and backslashes inside subsection names
- invalid section and option names
- duplicate-value behavior with Git-compatible option names

Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
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.

2 participants