fix: join backslash line continuations when reading config values - #2227
Merged
Byron merged 3 commits intoSep 4, 2026
Merged
Conversation
nkbeast
force-pushed
the
fix-config-backslash-continuation
branch
from
September 3, 2026 21:06
1f4913b to
22b4db5
Compare
git config joins an unquoted value that ends in a backslash with the next line: the backslash and the newline are removed and the next line is appended verbatim, so 'k = line1\' followed by ' line2' reads back as 'line1 line2'. GitPython only implemented multi-line values for quoted strings; for unquoted values the continuation line was silently dropped, truncating whatever was stored in the config. Read the continuation inside _read and join it, chaining across lines that themselves end in a backslash. An even number of trailing backslashes is an escaped one, so the value ends there; a single backslash right at end-of-file is dropped, matching git. Verified against git itself for every case covered by the new tests.
nkbeast
force-pushed
the
fix-config-backslash-continuation
branch
from
September 3, 2026 21:10
22b4db5 to
075a664
Compare
<!-- agent --> Git treats # and ; outside quotes as the start of a comment. A trailing backslash in that ignored text therefore cannot continue the value. The continuation loop counted trailing slashes without lexical context, so it consumed the next option and a later writable flush silently dropped that setting. - Track quote and escape state while checking the accumulated value. - Stop continuation scanning at an unquoted comment. - Cover preservation of the following option across a writable flush. Assisted-by: GPT 5.6 Co-authored-by: GPT 5.6 <codex@openai.com>
Git removes each backslash-newline pair before parsing the resulting logical value. Appending physical lines after processing only the first line left trailing whitespace, comments, quotes, and recognized escapes literal. That divergence returned values unlike git config and could preserve comment text as configuration data. - Accumulate continuation text before parsing it. - Apply whitespace, comment, quote, and escape handling once to the complete value. - Cover each affected syntax form with Git-compatible expectations. Assisted-by: GPT 5.6 Co-authored-by: GPT 5.6 <codex@openai.com>
Member
|
Thanks! As a note: The current Git configuration file parser is inherently insufficient and has many bugs. Fixing them all isn't the goal for GitPython 3.X, it's only remedy. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
git config joins an unquoted value that ends in a backslash with the next line: the backslash and the newline are removed and the next line is appended verbatim. Reproducing with git itself:
GitPython only implemented multi-line values for quoted strings. For unquoted values the continuation line was silently dropped —
GitConfigParserread backline1\and theline2content vanished, truncating whatever the user had stored (aliases, hook commands, any hand-edited multi-line value).The fix reads the continuation inside
_readand joins it, chaining across lines that themselves end in a backslash, with the exact rules git uses:val\\\\staysval\\\\)All five cases are asserted against git's own output in the new test.