FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix(repo): accept the explicit literal-path constructor option · gitpython-developers/GitPython@47a668c · GitHub

Repository navigation

Commit 47a668c

Browse files
authored andcommitted
fix(repo): accept the explicit literal-path constructor option
sbxloop 2.1.36 explicitly opens its metadata repositories with `Repo(..., expand_vars=False)` to keep repository paths literal. Removing the constructor option during the storage migration breaks 91 unchanged upstream cases before their Git queries run. Released GitPython 3.2.1 accepts the option. Restore the `False` constructor argument, including its fourth positional location, while retaining the branch's default literal environment-variable behavior. Reject `True` with a clear `ValueError` directing callers to expand inputs themselves. Initial tilde expansion and Git/Gix discovery remain as before; this input compatibility does not restore automatic environment expansion or introduce Python Git behavior. Document the limited restored contract and the remaining breaking path/API behavior. Add a fixture containing both a literal `$DOWNSTREAM_REPOSITORY` repository and an expansion target. Four SHA-1/SHA-256 and files/reftable regressions fail before the correction and verify literal contents, keyword/positional use, the unchanged default, and rejected expansion afterwards. Repository, CLI safety and downstream suites pass 189 tests, two skips and 14 subtests on each backend. Ruff lint/format, ShellCheck for the fixture, mypy for `git/repo/base.py` and `git diff --check` pass with Python 3.12.15, Git 2.53.0 and GixPython 0.2.0.
1 parent 4440302 commit 47a668c

5 files changed

Lines changed: 44 additions & 3 deletions

File tree

‎doc/gix-backend.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ fallbacks.
4545

4646
## Index and object metadata lifecycle
4747

48+
`Repo(..., expand_vars=False)` remains accepted for callers such as sbxloop
49+
2.1.36 that explicitly require literal paths. The default also keeps environment
50+
variables literal; `expand_vars=True` is unsupported. Callers wanting expansion
51+
must perform it before passing the path. Discovery still uses Gix/Git after
52+
ordinary input-path canonicalization.
53+
4854
`git.GitDB` and `git.db.GitDB` remain compatibility aliases for
4955
`GitCmdObjectDB`, so legacy `Repo(..., odbt=GitDB)` selectors use the same
5056
managed backend. Aider 0.86.2 uses that selector for every repository open.

‎doc/source/changes.rst‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,10 @@ API changes
156156
are removed; import from ``typing`` or the owning module. ``git.util`` now
157157
exposes the actual utility module. Abstract ``Traversable.traverse`` and
158158
``list_traverse`` raise ``NotImplementedError``; use concrete implementations.
159-
* Paths and URLs no longer expand ``$VAR``/``%VAR%`` automatically. Removed
160-
``expand_vars`` switches from ``Repo``, ``Repo.init``, ``expand_path``,
159+
* Paths and URLs no longer expand ``$VAR``/``%VAR%`` automatically. ``Repo``
160+
still accepts ``expand_vars=False`` for callers that explicitly select literal
161+
paths; ``True`` raises ``ValueError``. Removed ``expand_vars`` switches from
162+
``Repo.init``, ``expand_path``,
161163
``cygpath`` and ``Git.polish_url``. Expand explicitly with
162164
``os.path.expandvars`` if wanted; initial ``~`` expansion remains.
163165
``HIDE_WINDOWS_KNOWN_ERRORS`` and ``HIDE_WINDOWS_FREEZE_ERRORS`` are removed.

‎git/repo/base.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ def __init__(
238238
path: Optional[PathLike] = None,
239239
odbt: Type[GitCmdObjectDB] = GitCmdObjectDB,
240240
search_parent_directories: bool = False,
241+
expand_vars: bool = False,
241242
*,
242243
_env: Optional[Mapping[str, Optional[str]]] = None,
243244
) -> None:
@@ -274,6 +275,11 @@ def __init__(
274275
Please note that this was the default behaviour in older versions of
275276
GitPython, which is considered a bug though.
276277
278+
:param expand_vars:
279+
The legacy ``False`` option remains accepted to select literal paths.
280+
``True`` is unsupported; expand environment variables explicitly
281+
before opening a repository. Initial ``~`` expansion remains enabled.
282+
277283
:raise git.exc.InvalidGitRepositoryError:
278284
279285
:raise git.exc.NoSuchPathError:
@@ -286,6 +292,8 @@ def __init__(
286292
# process environment. Apply these overrides to discovery and later calls.
287293
if not isinstance(odbt, type) or not issubclass(odbt, GitCmdObjectDB):
288294
raise ValueError("odbt must be GitCmdObjectDB or a subclass")
295+
if expand_vars:
296+
raise ValueError("Environment variable expansion is unsupported; expand the path explicitly")
289297
environment = dict(_env or {})
290298
git_dir_env = environment.pop("GIT_DIR", os.getenv("GIT_DIR"))
291299
object_dir_env = environment.get("GIT_OBJECT_DIRECTORY", os.getenv("GIT_OBJECT_DIRECTORY"))

‎test/test_downstream_compatibility.py‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,22 @@
77
import git
88
import git.db
99

10-
from test.lib.fixtures import fixture_repo
10+
from test.lib.fixtures import fixture_repo, read_only_fixture
11+
12+
13+
@pytest.mark.parametrize("object_format", ["sha1", "sha256"])
14+
@pytest.mark.parametrize("ref_format", ["files", "reftable"])
15+
def test_repo_accepts_explicit_literal_path_selection(object_format, ref_format, monkeypatch):
16+
root = read_only_fixture("downstream-literal-repo.sh", object_format, ref_format)
17+
monkeypatch.setenv("DOWNSTREAM_REPOSITORY", str(root / "expanded"))
18+
literal = root / "$DOWNSTREAM_REPOSITORY"
19+
for kwargs in ({}, {"expand_vars": False}):
20+
with git.Repo(literal, **kwargs) as repo:
21+
assert repo.head.commit.tree["tracked"].data_stream.read() == b"$DOWNSTREAM_REPOSITORY"
22+
with git.Repo(literal, git.GitCmdObjectDB, False, False) as repo:
23+
assert Path(repo.working_tree_dir) == literal
24+
with pytest.raises(ValueError, match="Environment variable expansion is unsupported"):
25+
git.Repo(literal, expand_vars=True)
1126

1227

1328
@pytest.mark.parametrize("object_format", ["sha1", "sha256"])
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
set -eu
3+
# Preserve the literal variable spelling to detect accidental expansion.
4+
# shellcheck disable=SC2016
5+
for path in '$DOWNSTREAM_REPOSITORY' expanded; do
6+
git init -q --object-format="$1" --ref-format="$2" "$path"
7+
printf '%s' "$path" > "$path/tracked"
8+
git -C "$path" add tracked
9+
git -C "$path" commit -qm initial
10+
done

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL