From 7396683bfb12e632a8bee313b8ccd94d436a4178 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 22:47:32 +0000 Subject: [PATCH] fix: detect stale registry and reinstall git extension when directory missing Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/spec-kit/sessions/d5cbfcf4-4651-4784-9234-c4a42a333438 --- src/specify_cli/__init__.py | 10 ++++++++-- tests/test_branch_numbering.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index cb1a4495c..519371901 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -1199,9 +1199,15 @@ def _install_bundled_git_extension(project_path: Path) -> bool: from .extensions import ExtensionManager manager = ExtensionManager(project_path) - # Skip if already installed (e.g. via preset) + # Skip if already installed (e.g. via preset), but only if the + # on-disk extension manifest still exists. This guards against + # stale/corrupted registry entries. if manager.registry.is_installed("git"): - return True + ext_manifest = project_path / ".specify" / "extensions" / "git" / "extension.yml" + if ext_manifest.is_file(): + return True + # Registry is stale — remove entry so reinstall can proceed + manager.registry.remove("git") speckit_ver = get_speckit_version() manager.install_from_directory(ext_source, speckit_ver) diff --git a/tests/test_branch_numbering.py b/tests/test_branch_numbering.py index ed3004d1c..12f383905 100644 --- a/tests/test_branch_numbering.py +++ b/tests/test_branch_numbering.py @@ -138,3 +138,33 @@ class TestGitExtensionAutoInstall: # Only one entry in registry manager = ExtensionManager(project_dir) assert manager.registry.is_installed("git") + + def test_git_extension_reinstalls_when_directory_missing(self, tmp_path: Path): + """_install_bundled_git_extension should reinstall if registry says installed but directory is gone.""" + import shutil + from specify_cli import _install_bundled_git_extension + from specify_cli.extensions import ExtensionManager + + project_dir = tmp_path / "proj" + (project_dir / ".specify").mkdir(parents=True) + + # First install + result1 = _install_bundled_git_extension(project_dir) + assert result1 is True + + ext_dir = project_dir / ".specify" / "extensions" / "git" + assert ext_dir.is_dir() + + # Simulate stale registry: delete extension directory but keep registry + shutil.rmtree(ext_dir) + assert not ext_dir.exists() + + # Registry still says installed + manager = ExtensionManager(project_dir) + assert manager.registry.is_installed("git") + + # Re-install should detect missing directory and reinstall + result2 = _install_bundled_git_extension(project_dir) + assert result2 is True + assert ext_dir.is_dir(), "extension directory should be reinstalled" + assert (ext_dir / "extension.yml").is_file(), "extension.yml should be reinstalled"