You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sync_deletions: is_shallow_repository cannot distinguish "not shallow" from "could not tell" #17118
Discovered during #16310 (PR #17117), scoped out rather than folded in.
What
`services/git_subprocess.py`'s `run_git()` collapses every failure mode
(non-zero exit, timeout, spawn error) into the same `("", 1)` result — a
caller cannot tell "git ran and reported an error" from "git could not be
run at all" (missing binary, permission error, path does not exist).
So a `repo_root` that is broken for any reason (not a git repo, .git
corrupted, git binary unavailable) reads as `False` — "not shallow" —
identical to a genuinely full-depth repository.
Where it matters
`compute_bootstrap_plan`'s existing shallow guard: the ambiguity is
low-risk there, because a broken `repo_root` also fails the very next
git calls in the same function (`_tracked_paths_at_commit`,
`_ever_added_paths`), which correctly return an `error`-set
`DeletionPlan`.
`ensure_full_history()` (new in deploy: the builtin updater never removes files deleted from source, so deleted modules pile up on every host #16310/fix(updater): unshallow code_source and re-bootstrap legacy markers (#16310) #17117): here the ambiguity is
NOT self-correcting within the function — a broken `repo_root` makes
`is_shallow_repository` return `False`, and `ensure_full_history`
short-circuits to `return True, f"{repo_root} already has full
history"` — a false success for a repo it never actually inspected.
In the real call site (the ansible pre-flight task right after a
successful `ansible.builtin.git` clone/update of the same directory)
this is low-probability, and a broken `code_source` would still fail
loudly at the next task that runs git against it — but the function's
own contract is still wrong in isolation, and nothing currently catches
it if it is ever called against an unverified path.
Suggested fix
Give `run_git` (or a new helper) a way to distinguish "ran, exit
non-zero" from "could not run at all" — e.g. raising on spawn/timeout
failure rather than returning the same shape as a clean non-zero exit, or
returning an explicit tri-state. Requires auditing every existing caller
of `run_git`/`is_shallow_repository` (`services/sync_deletions.py`,
`services/full_tree_drift.py`) since the contract change is
cross-cutting — out of scope for a single-purpose deletion-planner fix.
Verified against merged main (8830293, post-#17147 consolidation). Not flagged by the consolidation as touched, but checked directly rather than assumed low-risk.
Tri-state fix — autobot-slm-backend/services/git_subprocess.py: ShallowCheck enum (SHALLOW/FULL/UNKNOWN) added; is_shallow_repository() returns it, mapping any non-zero run_git return code OR an unparseable rev-parse line to UNKNOWN rather than silently reading as "not shallow".
ensure_full_history no longer false-succeeds — explicit if status is ShallowCheck.UNKNOWN: return False, f"could not determine whether {repo_root} is a shallow clone" before the FULL-implies-success short-circuit; same UNKNOWN check repeated after the unshallow attempt.
Caller audit (both named in the issue):
services/sync_deletions.py:259-260: shallow_status = await is_shallow_repository(repo_root); if shallow_status is not ShallowCheck.FULL: — treats SHALLOW and UNKNOWN identically as "refuse to plan", with a reason string that names which case it was.
services/full_tree_drift.py: does not call is_shallow_repository at all (only run_git directly, for an unrelated ls-files call) — nothing to migrate there, confirmed by grep rather than assumed.
Suggested-fix scope fully delivered and intact on merged main, verified by reading source directly. Closing stands.
Correction: an earlier version of this comment additionally cited a local pytest re-run ("28 passed") as evidence. This project's standing rule treats a local run from a checkout as a design aid only, never evidence in a closing comment. Retracted — the file-read evidence above stands on its own.
Activity
Merge pull request #17147 from mrveiss/vehicle-v090-2026-09-20-batch
mrveiss commentedon Sep 20, 2026
Verified against merged main (8830293, post-#17147 consolidation). Not flagged by the consolidation as touched, but checked directly rather than assumed low-risk.
if status is ShallowCheck.UNKNOWN: return False, f"could not determine whether {repo_root} is a shallow clone"before the FULL-implies-success short-circuit; same UNKNOWN check repeated after the unshallow attempt.shallow_status = await is_shallow_repository(repo_root); if shallow_status is not ShallowCheck.FULL:— treats SHALLOW and UNKNOWN identically as "refuse to plan", with a reason string that names which case it was.Suggested-fix scope fully delivered and intact on merged main, verified by reading source directly. Closing stands.
Correction: an earlier version of this comment additionally cited a local pytest re-run ("28 passed") as evidence. This project's standing rule treats a local run from a checkout as a design aid only, never evidence in a closing comment. Retracted — the file-read evidence above stands on its own.
chore(vehicle): v0.9.1 — consolidate 6 ready PRs into one CI run (#17194