Skip to content

Commit f11722b

Browse files
committed
toolchain: keep coverage git calls out of the hook's GIT_DIR so precheck passes from worktrees
(cherry picked from commit 5ad5c85)
1 parent 2bf3f0d commit f11722b

3 files changed

Lines changed: 12 additions & 18 deletions

File tree

.github/scripts/check_coverage_map_health.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
"""Fail loudly if the committed coverage map is stale or under-covers. Used by coverage-health.yml."""
22
import datetime
3-
import subprocess
43
import sys
54
from pathlib import Path
65

76
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "toolchain"))
8-
from mfc.test.coverage import COVERAGE_MAP_PATH, load_map, map_health # noqa: E402
7+
from mfc.test.coverage import COVERAGE_MAP_PATH, _git, load_map, map_health # noqa: E402
98
from mfc.test.cases import list_cases # noqa: E402 (returns the current test list)
109

1110
MAX_AGE_DAYS = 10
@@ -40,7 +39,7 @@ def verified_sha(cwd=None):
4039
caller must read that as undeterminable and fall back to the wall-clock age rule, not
4140
as a failure -- an absent ref is not evidence of a broken refresh.
4241
"""
43-
rev = subprocess.run(["git", "rev-parse", "--verify", "--quiet", f"{VERIFIED_REF}^{{commit}}"], capture_output=True, text=True, check=False, cwd=cwd)
42+
rev = _git(["rev-parse", "--verify", "--quiet", f"{VERIFIED_REF}^{{commit}}"], cwd)
4443
return rev.stdout.strip() or None
4544

4645

@@ -53,10 +52,10 @@ def verified_after_last_change(git_sha, cwd=None):
5352
"""
5453
if not git_sha:
5554
return None
56-
last = subprocess.run(["git", "log", "-1", "--format=%H", "--", *COVERAGE_RELEVANT_PATHS], capture_output=True, text=True, check=False, cwd=cwd)
55+
last = _git(["log", "-1", "--format=%H", "--", *COVERAGE_RELEVANT_PATHS], cwd)
5756
if last.returncode != 0 or not last.stdout.strip():
5857
return None # shallow clone or no such commit -> fall back to the age rule
59-
ancestor = subprocess.run(["git", "merge-base", "--is-ancestor", last.stdout.strip(), git_sha], capture_output=True, check=False, cwd=cwd)
58+
ancestor = _git(["merge-base", "--is-ancestor", last.stdout.strip(), git_sha], cwd)
6059
return {0: True, 1: False}.get(ancestor.returncode) # anything else -> None (unknown sha, shallow history)
6160

6261

toolchain/mfc/test/coverage.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,14 @@ def select_tests(cases, coverage_map, changed_files):
216216
return to_run, skipped, f"selected {len(to_run)}/{len(cases)} by coverage overlap"
217217

218218

219+
def _env_without_git():
220+
# Git exports GIT_DIR and GIT_INDEX_FILE to hooks, and neither cwd nor `git -C` overrides them:
221+
# under the pre-commit hook every call below would otherwise act on the committing repository.
222+
return {k: v for k, v in os.environ.items() if not k.startswith("GIT_")}
223+
224+
219225
def _git(args, cwd, timeout=60):
220-
return subprocess.run(["git", *args], capture_output=True, text=True, cwd=cwd, timeout=timeout, check=False)
226+
return subprocess.run(["git", *args], capture_output=True, text=True, cwd=cwd, timeout=timeout, check=False, env=_env_without_git())
221227

222228

223229
def _merge_base(cwd, branch):

toolchain/mfc/test/test_coverage_unit.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from pathlib import Path
77
from unittest.mock import patch
88

9-
from mfc.test.coverage import canonicalize_param_paths, entries_equal, format_summary, get_changed_files, is_always_run_all, load_map, map_health, param_hash, save_map, select_tests
9+
from mfc.test.coverage import _env_without_git, canonicalize_param_paths, entries_equal, format_summary, get_changed_files, is_always_run_all, load_map, map_health, param_hash, save_map, select_tests
1010

1111

1212
def test_param_hash_is_order_independent():
@@ -462,17 +462,6 @@ def test_health_fails_immediately_when_no_refresh_ran_since_last_source_change()
462462
CHANGED_SCRIPT = Path(__file__).resolve().parents[3] / ".github" / "scripts" / "coverage_map_changed.py"
463463

464464

465-
def _env_without_git():
466-
"""The environment minus every GIT_* variable.
467-
468-
`git -C <dir>` changes directory but does NOT override an inherited GIT_DIR or
469-
GIT_INDEX_FILE. Git exports both when it runs a hook, and MFC's pre-commit hook runs
470-
precheck, which runs this suite -- so without this scrub the commits below are made
471-
against the real repository instead of the throwaway one.
472-
"""
473-
return {k: v for k, v in os.environ.items() if not k.startswith("GIT_")}
474-
475-
476465
def _repo_with_committed_map(d, entries):
477466
"""A throwaway git repo whose HEAD holds `entries` as the coverage map."""
478467
repo = Path(d)

0 commit comments

Comments
 (0)