Skip to content

Commit cbea203

Browse files
EliahKaganclaude
andcommitted
Add a test that required submodules are initialized
Adds `test_required_submodule_is_initialized` to `test/test_fixture_health.py`. For each of the gitdb and smmap submodule working trees -- present within the GitPython source tree at `git/ext/gitdb` and `git/ext/gitdb/gitdb/ext/smmap` respectively -- asserts that the working tree directory exists and contains a `.git` marker (file or directory). Failure prints an actionable message naming `init-tests-after-clone.sh` as the remedy. This is a regression test for a different contract than the existing `test_fixture_dir_is_trusted_by_git` in this module. That test verifies git's willingness to operate in each fixture directory (the `safe.directory` / dubious-ownership contract). The new test verifies that the directories are populated at all (the `init-tests-after-clone.sh` contract). A bug class along these lines affected Arch Linux in gitpython-developers#1713 when `init-tests-after-clone.sh` stopped running `git submodule update` on CI. When the source tree's submodule directories are empty, this test fails with a message naming `init-tests-after-clone.sh` as the remedy, instead of leaving the issue to be diagnosed only after a cascade of test failures elsewhere in the suite. 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 511212a commit cbea203

1 file changed

Lines changed: 42 additions & 0 deletions

File tree

test/test_fixture_health.py

Lines changed: 42 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,32 @@ 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 ``init-tests-after-clone.sh``
112+
(or its equivalent) hasn't been run, so the submodule's working tree has
113+
not been populated. Skipped when the source tree itself isn't a git clone
114+
(e.g. an extracted release tarball), since ``git submodule update`` cannot
115+
operate there; setups that handle submodules in a separately-prepared
116+
tree (via ``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+
assert submodule_dir.is_dir(), (
126+
f"Submodule working tree missing: {submodule_dir}.\nRun ./init-tests-after-clone.sh from the repo root."
127+
)
128+
assert (submodule_dir / ".git").exists(), (
129+
f"Submodule directory exists but has no .git marker: {submodule_dir}.\n"
130+
"This usually means the directory was created (e.g. by extracting a "
131+
"source tarball) but `git submodule update --init` was never run for "
132+
"it. Run ./init-tests-after-clone.sh from the repo root."
133+
)

0 commit comments

Comments
 (0)