Files

71 lines
2.2 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Git command 执行工具。
所有 Trellis script 运行 git command 的唯一事实来源。
"""
from __future__ import annotations
import subprocess
from pathlib import Path
def run_git(
args: list[str],
cwd: Path | None = None,
timeout: float | None = None,
) -> tuple[int, str, str]:
"""运行 git command,并返回 (returncode, stdout, stderr)。
使用 `-c i18n.logOutputEncoding=UTF-8` 和 UTF-8 编码,确保 Windows、macOS、Linux
上的输出一致。调用方可以为尽力而为的探测提供 timeout;普通 Git 操作默认不设上限。
"""
try:
git_args = ["git", "-c", "i18n.logOutputEncoding=UTF-8"] + args
result = subprocess.run(
git_args,
cwd=cwd,
capture_output=True,
text=True,
encoding="utf-8",
errors="replace",
timeout=timeout,
)
return result.returncode, result.stdout, result.stderr
except Exception as e:
return 1, "", str(e)
def resolve_default_branch(repo_root: Path) -> str | None:
"""解析仓库默认 branch(origin/HEAD 目标)。
先尝试本地 `refs/remotes/origin/HEAD` symbolic ref(不访问网络),再回退到
`git remote show origin`(可能访问网络,也能修复缺失或过期的 symbolic-ref)。两者
都无法解析时返回 None,由调用方回退到原有行为。
"""
rc, out, _ = run_git(["symbolic-ref", "refs/remotes/origin/HEAD"], cwd=repo_root)
if rc == 0 and out.strip():
return out.strip().rsplit("/", 1)[-1]
rc, out, _ = run_git(["remote", "show", "origin"], cwd=repo_root)
if rc == 0:
for line in out.splitlines():
line = line.strip()
if line.startswith("HEAD branch:"):
branch = line.split(":", 1)[1].strip()
if branch and branch != "(unknown)":
return branch
return None
def branch_exists_locally(branch: str, repo_root: Path) -> bool:
"""检查仓库中是否存在本地 branch ref。"""
if not branch:
return False
rc, _, _ = run_git(
["rev-parse", "--verify", "--quiet", f"refs/heads/{branch}"],
cwd=repo_root,
)
return rc == 0