Skip to content

Config lookups are case-sensitive, where git's section and variable names are not #2240

Description

@rawsun007

git matches section names and variable names case-insensitively; only the subsection between quotes is case-sensitive. GitConfigParser matches all three exactly, so a config written with different casing is unreadable through it.

Against this file:

[core]
	BigName = 1
[REMOTE "Origin"]
	url = u
lookup                      git         GitPython
core.BigName                1           1
core.bigname                1           NoOptionError
REMOTE "Origin".url         u           u
remote "Origin".url         u           NoSectionError

The variable half comes from optionxform being overridden to identity (git/config.py:439):

def optionxform(self, optionstr: str) -> str:
    """Do not transform options in any way when writing."""
    return optionstr

The docstring says "when writing", and preserving case on write is right, since git keeps the spelling it was given. The same function decides how lookups are matched though, so reads inherit it.

This bites when the file was written by something other than GitPython: git itself preserves whatever casing the user typed, and other tools emit [remote "x"] or [Remote "x"] interchangeably, so repo.config_reader().get_value("remote \"x\"", "url") can raise on a perfectly valid config.

I have not sent a patch because the fix is a behaviour change with more than one shape: case-folding lookups only, or folding on read while keeping the written spelling, and either way sections() and items() start returning something different from what they return today. Happy to do it if you say which.

Unrelated to #2237, which I filed yesterday about valueless keys, but both are in the same _read/lookup path so you may want to look at them together.

git 2.50.1, GitPython at a9913c7.

Assisted-by: Claude Opus 5 (Claude Code), per the identification rule in CONTRIBUTING.md.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions