mirror of
https://github.com/cita-777/metapi.git
synced 2026-11-02 05:05:37 +08:00
71 lines
2.2 KiB
Python
Executable File
71 lines
2.2 KiB
Python
Executable File
"""
|
||
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
|