fix(worktrees): reuse project root for current branch (#77)
This commit is contained in:
+18
-2
@@ -4,7 +4,13 @@ from pathlib import Path
|
|||||||
|
|
||||||
from .config import ProjectConfig, ProjectsConfig
|
from .config import ProjectConfig, ProjectsConfig
|
||||||
from .context import RunContext
|
from .context import RunContext
|
||||||
from .utils.git import git_is_worktree, git_ok, git_run, resolve_default_base
|
from .utils.git import (
|
||||||
|
git_is_worktree,
|
||||||
|
git_ok,
|
||||||
|
git_run,
|
||||||
|
git_stdout,
|
||||||
|
resolve_default_base,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class WorktreeError(RuntimeError):
|
class WorktreeError(RuntimeError):
|
||||||
@@ -23,7 +29,10 @@ def resolve_run_cwd(
|
|||||||
raise WorktreeError(f"unknown project {context.project!r}")
|
raise WorktreeError(f"unknown project {context.project!r}")
|
||||||
if context.branch is None:
|
if context.branch is None:
|
||||||
return project.path
|
return project.path
|
||||||
return ensure_worktree(project, context.branch)
|
branch = _sanitize_branch(context.branch)
|
||||||
|
if _matches_project_branch(project.path, branch):
|
||||||
|
return project.path
|
||||||
|
return ensure_worktree(project, branch)
|
||||||
|
|
||||||
|
|
||||||
def ensure_worktree(project: ProjectConfig, branch: str) -> Path:
|
def ensure_worktree(project: ProjectConfig, branch: str) -> Path:
|
||||||
@@ -112,6 +121,13 @@ def _sanitize_branch(branch: str) -> str:
|
|||||||
return cleaned
|
return cleaned
|
||||||
|
|
||||||
|
|
||||||
|
def _matches_project_branch(root: Path, branch: str) -> bool:
|
||||||
|
current = git_stdout(["branch", "--show-current"], cwd=root)
|
||||||
|
if not current:
|
||||||
|
return False
|
||||||
|
return current == branch
|
||||||
|
|
||||||
|
|
||||||
def _ensure_within_root(root: Path, path: Path) -> None:
|
def _ensure_within_root(root: Path, path: Path) -> None:
|
||||||
root_resolved = root.resolve(strict=False)
|
root_resolved = root.resolve(strict=False)
|
||||||
path_resolved = path.resolve(strict=False)
|
path_resolved = path.resolve(strict=False)
|
||||||
|
|||||||
@@ -34,6 +34,29 @@ def test_resolve_run_cwd_rejects_invalid_branch(tmp_path: Path) -> None:
|
|||||||
resolve_run_cwd(ctx, projects=projects)
|
resolve_run_cwd(ctx, projects=projects)
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_run_cwd_uses_root_when_branch_matches(
|
||||||
|
monkeypatch, tmp_path: Path
|
||||||
|
) -> None:
|
||||||
|
projects = _projects_config(tmp_path)
|
||||||
|
|
||||||
|
def _fake_stdout(args, **_kwargs):
|
||||||
|
if args == ["branch", "--show-current"]:
|
||||||
|
return "main"
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _unexpected(*_args, **_kwargs):
|
||||||
|
raise AssertionError("unexpected")
|
||||||
|
|
||||||
|
monkeypatch.setattr("takopi.worktrees.git_stdout", _fake_stdout)
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"takopi.worktrees.ensure_worktree",
|
||||||
|
_unexpected,
|
||||||
|
)
|
||||||
|
|
||||||
|
ctx = RunContext(project="z80", branch="main")
|
||||||
|
assert resolve_run_cwd(ctx, projects=projects) == tmp_path
|
||||||
|
|
||||||
|
|
||||||
def test_ensure_worktree_creates_from_base(monkeypatch, tmp_path: Path) -> None:
|
def test_ensure_worktree_creates_from_base(monkeypatch, tmp_path: Path) -> None:
|
||||||
project = ProjectConfig(
|
project = ProjectConfig(
|
||||||
alias="z80",
|
alias="z80",
|
||||||
|
|||||||
Reference in New Issue
Block a user