Skip to content

Commit cb518e3

Browse files
EliahKaganclaude
andcommitted
Add a test that required submodules are initialized
This adds the new test, `test_required_submodule_is_initialized`, to `test_fixture_health.py`. For the gitdb and smmap submodules, the test asserts that the working tree directory exists and contains a `.git` marker (file or directory). The failure message reminds the developer to run `git submodule update --init --recursive`. This is a regression test for a different contract than the preexisting `test_fixture_dir_is_trusted_by_git` in `test_fixture_health.py`. That test verifies git's willingness to operate in each fixture directory (the `safe.directory` / dubious-ownership contract). This one verifies that the directories are populated at all. When the gitdb and smmap submodules aren't populated, the rest of the suite fails in ways that don't name the cause: a cascade of failures across `test_docs.py`, `test_repo.py`, and `test_submodule.py` -- tests that need submodule content but don't set out to check for it. That cascade was the failure mode of gitpython-developers#1713 on the Arch Linux build, where `init-tests-after-clone.sh` had stopped running `git submodule update` on CI. Wherever the submodules are actually missing, this test reports the missing path directly instead. The test skips when the source tree is not a git clone (no `.git` at `REPO_ROOT`). This is to accommodate setups that run pytest from an extracted release tarball and prepare submodules in a separately-pointed tree via `GIT_PYTHON_TEST_GIT_REPO_BASE` (e.g. OpenIndiana's package build). In such setups, `git submodule update` cannot operate on the source tree, and the submodule paths checked here would never be populated there, but the test suite still works because `rorepo` points elsewhere. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0081133 commit cb518e3

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

test/test_fixture_health.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@
4545
),
4646
]
4747

48+
# Submodule working trees that must be present and initialized for the
49+
# test suite to operate normally: gitdb at `git/ext/gitdb`, and smmap
50+
# nested inside gitdb at `git/ext/gitdb/gitdb/ext/smmap`. The paths
51+
# below are anchored at REPO_ROOT (the GitPython source tree), not at
52+
# any rorepo redirection target.
53+
SUBMODULE_DIRS = [
54+
pytest.param(REPO_ROOT / "git" / "ext" / "gitdb", id="gitdb"),
55+
pytest.param(
56+
REPO_ROOT / "git" / "ext" / "gitdb" / "gitdb" / "ext" / "smmap",
57+
id="smmap",
58+
),
59+
]
60+
4861

4962
@pytest.mark.parametrize("fixture_dir", FIXTURE_DIRS)
5063
def test_fixture_dir_is_trusted_by_git(fixture_dir: Path) -> None:
@@ -89,3 +102,40 @@ def test_fixture_dir_is_trusted_by_git(fixture_dir: Path) -> None:
89102
"This usually means the directory is not an initialized git "
90103
"repository (its `.git` marker may be stale or pointing elsewhere)."
91104
)
105+
106+
107+
@pytest.mark.parametrize("submodule_dir", SUBMODULE_DIRS)
108+
def test_required_submodule_is_initialized(submodule_dir: Path) -> None:
109+
"""The submodule's working tree is present and initialized.
110+
111+
Failure means the source tree is a git clone but the submodule's
112+
working tree hasn't been populated. Skipped when the source tree
113+
itself isn't a git clone (e.g. an extracted release tarball), since
114+
``git submodule update`` cannot operate there; setups that handle
115+
submodules in a separately-prepared tree (via
116+
``GIT_PYTHON_TEST_GIT_REPO_BASE``) are exempted from this check.
117+
"""
118+
if not (REPO_ROOT / ".git").exists():
119+
pytest.skip(
120+
"Source tree is not a git clone (no .git in REPO_ROOT); submodules "
121+
"cannot be initialized via `git submodule update` here. Setups "
122+
"that prepare submodules in a separately-pointed tree (via "
123+
"GIT_PYTHON_TEST_GIT_REPO_BASE) are exempted from this check."
124+
)
125+
# The assertion messages below recommend `git submodule update --init
126+
# --recursive` rather than `init-tests-after-clone.sh`, even though the
127+
# latter is the documented entry point for first-time test setup. Two
128+
# reasons: the script performs `git reset --hard` operations that can
129+
# destroy local work, and #1713 showed the script itself can carry
130+
# submodule-init regressions, in which case recommending it would lead
131+
# developers in a circle. The direct git command is a safe minimal fix
132+
# for this test's specific failure mode and bypasses any such regression.
133+
assert submodule_dir.is_dir(), (
134+
f"Submodule working tree missing: {submodule_dir}.\n"
135+
"Run `git submodule update --init --recursive` from the repo root."
136+
)
137+
assert (submodule_dir / ".git").exists(), (
138+
f"Submodule directory exists but has no .git marker: {submodule_dir}.\n"
139+
"The submodule hasn't been initialized. "
140+
"Run `git submodule update --init --recursive` from the repo root."
141+
)

0 commit comments

Comments
 (0)