Skip to content

fix(repo): unquote git check-ignore paths in Repo.ignored - #2298

Merged
Byron merged 1 commit into
gitpython-developers:mainfrom
Keerthana-64:repo-ignored-nul-paths
Oct 21, 2026
Merged

Byron merged 1 commit into
gitpython-developers:mainfrom
Keerthana-64:repo-ignored-nul-paths

Conversation

@Keerthana-64

Copy link
Copy Markdown
Contributor

repo.ignored ran git check-ignore -- <paths> and undid git's c-quoting with two string replaces, which does not reverse it: with *.env ignored, données.env came back as donn\303\251es.env, q"uote.env as q\uote.env and tab<TAB>.env as tab\t.env, so a caller that matches the result against its own paths, for example to keep ignored files out of a commit or an upload, treats those files as not ignored. read stdout as bytes and unquote quoted lines with the existing _unquote_path from git/diff.py; splitting at line feeds stays safe because git quotes any path containing one, and -z is not usable here since git accepts it only with --stdin. the new test in test/test_repo.py fails before the change and passes after.

`Repo.ignored` runs `git check-ignore -- <paths>` and recovered the
matched paths from stdout with
`.replace("\\\\", "\\").replace('"', "").split("\n")`. git C-quotes a
path that contains a non-ASCII byte (with the default `core.quotePath`),
a double quote, a backslash or a control character, and that replacement
does not reverse the quoting. With `*.env` in `.gitignore`:

- `données.env` came back as `donn\303\251es.env`
- `q"uote.env` came back as `q\uote.env`
- `tab<TAB>.env` came back as `tab\t.env`
- a name containing a line feed came back with a literal `\n`

A caller that compares the result with the paths it passed in, for
example to leave ignored files out of a commit, an upload or an archive,
therefore treats those ignored files as not ignored.

Read stdout as bytes and unquote each quoted line with
`git.diff._unquote_path`, which already reverses git's C-quoting for
patch headers. Splitting at line feeds stays safe because git always
quotes a path that contains one. `git check-ignore -z` would avoid the
quoting, but git accepts `-z` only together with `--stdin`. Paths git
does not quote are returned unchanged.

Adds `test_ignored_items_reported_verbatim` to `test/test_repo.py`; it
fails before this change and passes after. `ruff check`,
`ruff format --check` and `mypy` pass. The full pytest suite run locally
fails the same 83 tests with and without this change; those failures
come from fixture commits missing in the local clone, not from this
change.
@Byron
Byron merged commit a3b2f15 into gitpython-developers:main Oct 21, 2026
87 of 90 checks passed
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