akg-factor-bridge/version.py

52 lines
2.0 KiB
Python
Raw Permalink Normal View History

"""代码版本号:解析挂载进容器的 .git 文件取短哈希,不需要 git 二进制。
## 为什么要有它
计划快照要带代码版本复盘时才知道某天的候选单是哪一版规则算出来的桥镜像是
python:3.11-slim没装 gitfreeze.py 里调 git 命令的取法在容器里恒为 unknown
155 data/frozen/2026-09-01/manifest.json 实测仓库根挂在 /app.git 目录随之
挂进来直接读它就够了2026-09-02 拍板解析 .git 文件不走宿主传环境变量
读法.git/HEAD "ref: refs/heads/<分支>" 就去读对应的 refs 文件refs 文件不存在
打包过就在 .git/packed-refs 里找那一行HEAD 本身就是裸哈希游离头直接用
任何一步失败返回 "unknown"绝不抛错版本号缺失不该让计划断产
"""
from __future__ import annotations
from pathlib import Path
def _read(p: Path) -> str | None:
try:
return p.read_text(encoding="utf-8").strip()
except OSError:
return None
def git_short_rev(repo_root: str | Path | None = None, length: int = 7) -> str:
roots = [Path(repo_root)] if repo_root else [Path("/app"), Path(__file__).resolve().parent]
for root in roots:
git = root / ".git"
head = _read(git / "HEAD")
if not head:
continue
if head.startswith("ref:"):
ref = head.split(":", 1)[1].strip()
sha = _read(git / ref)
if not sha:
packed = _read(git / "packed-refs") or ""
for line in packed.splitlines():
parts = line.split()
if len(parts) == 2 and parts[1] == ref:
sha = parts[0]
break
else:
sha = head
if sha and len(sha) >= length and all(c in "0123456789abcdef" for c in sha[:length]):
return sha[:length]
return "unknown"
if __name__ == "__main__":
print(git_short_rev())