mirror of
https://ghfast.top/https://github.com/aeroxw/tick-stock-panel.git
synced 2026-09-12 19:04:15 +08:00
feat(v0.2): 完善量化研究与二次开发能力
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Read-only Git overlap and conflict preview for secondary-development branches."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _git(root: Path, *args: str, check: bool = True) -> subprocess.CompletedProcess[str]:
|
||||
result = subprocess.run(
|
||||
["git", *args],
|
||||
cwd=root,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
if check and result.returncode != 0:
|
||||
detail = (result.stderr or result.stdout).strip()
|
||||
raise RuntimeError(detail or f"git {' '.join(args)} failed")
|
||||
return result
|
||||
|
||||
|
||||
def _lines(result: subprocess.CompletedProcess[str]) -> set[str]:
|
||||
return {line.strip() for line in result.stdout.splitlines() if line.strip()}
|
||||
|
||||
|
||||
def _resolve_repo(path: Path) -> Path:
|
||||
result = _git(path, "rev-parse", "--show-toplevel")
|
||||
return Path(result.stdout.strip()).resolve()
|
||||
|
||||
|
||||
def _resolve_commit(root: Path, ref: str) -> str:
|
||||
return _git(root, "rev-parse", "--verify", f"{ref}^{{commit}}").stdout.strip()
|
||||
|
||||
|
||||
def _merge_tree_conflicts(root: Path, base: str, current: str, target: str) -> list[str]:
|
||||
result = _git(root, "merge-tree", base, current, target)
|
||||
lines = result.stdout.splitlines()
|
||||
conflicts: list[str] = []
|
||||
current_path: str | None = None
|
||||
current_conflicted = False
|
||||
for line in [*lines, ""]:
|
||||
if line in {"changed in both", "added in both", "removed in both"}:
|
||||
if current_path and current_conflicted:
|
||||
conflicts.append(current_path)
|
||||
current_path = None
|
||||
current_conflicted = False
|
||||
continue
|
||||
parts = line.strip().split()
|
||||
if current_path is None and len(parts) >= 4 and parts[0] in {"base", "our", "their"}:
|
||||
current_path = parts[-1]
|
||||
if line.startswith("+<<<<<<< ") or line.startswith("+=======") or line.startswith("+>>>>>>> "):
|
||||
current_conflicted = True
|
||||
if current_path and current_conflicted:
|
||||
conflicts.append(current_path)
|
||||
return sorted(set(conflicts))
|
||||
|
||||
|
||||
def _print_paths(title: str, paths: list[str]) -> None:
|
||||
print(f"\n{title}: {len(paths)}")
|
||||
for path in paths:
|
||||
print(f" - {path}")
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="只读检查当前二开分支升级到目标 Git ref 时的源码重叠与文本冲突",
|
||||
)
|
||||
parser.add_argument("target", help="目标 Tag/分支/commit, 例如 v0.3.1")
|
||||
parser.add_argument(
|
||||
"--repo",
|
||||
type=Path,
|
||||
default=Path.cwd(),
|
||||
help="仓库路径, 默认当前目录",
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
try:
|
||||
root = _resolve_repo(args.repo.resolve())
|
||||
current = _resolve_commit(root, "HEAD")
|
||||
target = _resolve_commit(root, args.target)
|
||||
base = _git(root, "merge-base", current, target).stdout.strip()
|
||||
if not base:
|
||||
raise RuntimeError("当前分支与目标版本没有共同基线")
|
||||
|
||||
current_paths = _lines(_git(root, "diff", "--name-only", f"{base}..{current}"))
|
||||
target_paths = _lines(_git(root, "diff", "--name-only", f"{base}..{target}"))
|
||||
overlap = sorted(current_paths & target_paths)
|
||||
conflicts = _merge_tree_conflicts(root, base, current, target)
|
||||
dirty = sorted(_lines(_git(root, "status", "--short")))
|
||||
|
||||
print("Tick Stock Panel 二开升级预检")
|
||||
print(f"仓库: {root}")
|
||||
print(f"当前: {current[:12]}")
|
||||
print(f"目标: {args.target} ({target[:12]})")
|
||||
print(f"共同基线: {base[:12]}")
|
||||
print(f"当前分支修改文件: {len(current_paths)}")
|
||||
print(f"目标版本修改文件: {len(target_paths)}")
|
||||
_print_paths("双方修改的同一文件", overlap)
|
||||
_print_paths("Git 三方预演识别的文本冲突", conflicts)
|
||||
|
||||
if dirty:
|
||||
print(f"\n未提交工作区条目: {len(dirty)}")
|
||||
print(" 注意: 未提交内容不会进入 Git 三方预演, 请先提交到临时分支后再复检。")
|
||||
if conflicts:
|
||||
print("\n结论: 需要人工解决文本冲突并执行完整回归。")
|
||||
return 2
|
||||
if overlap:
|
||||
print("\n结论: Git 未发现文本冲突, 但重叠文件需要检查语义兼容和测试。")
|
||||
return 0
|
||||
print("\n结论: 未发现源码重叠; 仍需执行目标版本的验证矩阵。")
|
||||
return 0
|
||||
except (OSError, RuntimeError) as exc:
|
||||
print(f"升级预检失败: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user