Skip to content

Commit f86acf5

Browse files
codexByron
andcommitted
feat: rewrite config parser to be consistent with Git
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 <[email protected]>
1 parent ecd6844 commit f86acf5

5 files changed

Lines changed: 352 additions & 181 deletions

File tree

0 commit comments

Comments
 (0)