升级本机 Trellis 至 0.6.12(upgrade-trellis-0-6-12)

这个提交包含在:
2026-08-02 16:46:56 +08:00
父节点 45dc86c27a
当前提交 1c557e4926
共修改 19 个文件,包含 335 行新增和 50 行删除
+64 -11
查看文件
@@ -17,6 +17,7 @@ import json
import os
import re
import subprocess
import sys
from pathlib import Path
from .active_task import resolve_context_key
@@ -64,11 +65,17 @@ _POLYREPO_IGNORED_DIRS = {
"__pycache__",
}
_POLYREPO_SCAN_MAX_DEPTH = 2
_POLYREPO_SCAN_MAX_REPOS = 8
_GIT_PROBE_TIMEOUT_SECONDS = 2.0
def _is_git_worktree(path: Path) -> bool:
"""Return True when path is inside a Git worktree."""
rc, out, _ = run_git(["rev-parse", "--is-inside-work-tree"], cwd=path)
rc, out, _ = run_git(
["rev-parse", "--is-inside-work-tree"],
cwd=path,
timeout=_GIT_PROBE_TIMEOUT_SECONDS,
)
return rc == 0 and out.strip().lower() == "true"
@@ -91,13 +98,27 @@ def _collect_git_repo_info(name: str, rel_path: str, repo_dir: Path) -> dict | N
if not (repo_dir / ".git").exists():
return None
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_dir)
status_rc, status_out, _ = run_git(
["status", "--porcelain"],
cwd=repo_dir,
timeout=_GIT_PROBE_TIMEOUT_SECONDS,
)
if status_rc != 0:
return None
changes = len([line for line in status_out.splitlines() if line.strip()])
_, branch_out, _ = run_git(
["branch", "--show-current"],
cwd=repo_dir,
timeout=_GIT_PROBE_TIMEOUT_SECONDS,
)
branch = branch_out.strip() or "unknown"
_, status_out, _ = run_git(["status", "--porcelain"], cwd=repo_dir)
changes = len([l for l in status_out.splitlines() if l.strip()])
_, log_out, _ = run_git(["log", "--oneline", "-5"], cwd=repo_dir)
_, log_out, _ = run_git(
["log", "--oneline", "-5"],
cwd=repo_dir,
timeout=_GIT_PROBE_TIMEOUT_SECONDS,
)
return {
"name": name,
@@ -120,20 +141,36 @@ def _collect_root_git_info(repo_root: Path) -> dict:
"recentCommits": [],
}
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_root)
_, branch_out, _ = run_git(
["branch", "--show-current"],
cwd=repo_root,
timeout=_GIT_PROBE_TIMEOUT_SECONDS,
)
branch = branch_out.strip() or "unknown"
_, status_out, _ = run_git(["status", "--porcelain"], cwd=repo_root)
status_rc, status_out, _ = run_git(
["status", "--porcelain"],
cwd=repo_root,
timeout=_GIT_PROBE_TIMEOUT_SECONDS,
)
status_lines = [line for line in status_out.splitlines() if line.strip()]
_, short_out, _ = run_git(["status", "--short"], cwd=repo_root)
_, short_out, _ = run_git(
["status", "--short"],
cwd=repo_root,
timeout=_GIT_PROBE_TIMEOUT_SECONDS,
)
_, log_out, _ = run_git(["log", "--oneline", "-5"], cwd=repo_root)
_, log_out, _ = run_git(
["log", "--oneline", "-5"],
cwd=repo_root,
timeout=_GIT_PROBE_TIMEOUT_SECONDS,
)
return {
"isRepo": True,
"branch": branch,
"isClean": len(status_lines) == 0,
"isClean": status_rc == 0 and len(status_lines) == 0,
"uncommittedChanges": len(status_lines),
"statusShort": short_out.splitlines(),
"recentCommits": _parse_recent_commits(log_out),
@@ -143,12 +180,16 @@ def _collect_root_git_info(repo_root: Path) -> dict:
def _discover_child_git_repos(repo_root: Path) -> list[tuple[str, str]]:
"""Discover child Git repositories using the init-time polyrepo heuristic."""
found: list[str] = []
overflow = False
def is_candidate_dir(path: Path) -> bool:
name = path.name
return not name.startswith(".") and name not in _POLYREPO_IGNORED_DIRS
def scan(rel_dir: Path, depth: int) -> None:
nonlocal overflow
if overflow:
return
if depth >= _POLYREPO_SCAN_MAX_DEPTH:
return
abs_dir = repo_root / rel_dir
@@ -165,11 +206,23 @@ def _discover_child_git_repos(repo_root: Path) -> list[tuple[str, str]]:
rel_dir / child.name if rel_dir != Path(".") else Path(child.name)
)
if (child / ".git").exists():
if len(found) >= _POLYREPO_SCAN_MAX_REPOS:
overflow = True
return
found.append(child_rel.as_posix())
continue
scan(child_rel, depth + 1)
scan(Path("."), 0)
if overflow:
print(
"warning: found more than "
f"{_POLYREPO_SCAN_MAX_REPOS} child Git repositories; "
"skipping automatic Git status collection. Configure explicit "
"packages entries with path and git: true in .trellis/config.yaml.",
file=sys.stderr,
)
return []
if len(found) < 2:
return []
return [(path.replace("/", "_"), path) for path in sorted(found)]