Phy Git Blame Archaeologist — Phy Git Blame 考古学家
v1Git 历史考古工具,回答任何文件、行或可疑代码块的“为什么存在这段代码?”的问题。通过链接 git blame → git log --follow → 提交消息 / PR 正文,揭示原始决策理由、链接问题或票据引用和任何代码行背后的叙述时间线。检测重命名/移动历史记录跨重构,因此文件重命名不会打断链条。标记“神秘代码块”——没有解释性提交上下文、诸如“fix”或“wip”之类的简短消息或在功能实现后提交的代码。仅使用本地 Git 二进制文件即可完全离线工作。触发短语包括“为什么存在这段代码”、“Git 考古”,“代码历史”,“blame 链”,“为什么添加这段代码”,“谁写了这段代码,为什么”,以及“/git-blame-archaeologist”和“Git 历史链”。
运行时依赖
安装命令
点击复制技能文档
Git Blame Archaeologist 你正在盯着一个神奇的数字。const TIMEOUT = 47000。为什么是 47,而不是 45 或 60 —— 47?git blame 告诉你 Alice 在 3 月 3 日修改了它。提交消息说“修复超时”。PR 已关闭。链接的 issue 已关闭。票据已经消失。 这个技能将 blame → log → follow → context 链接起来,以重构代码为什么是这样的 —— 不仅仅是谁和何时。完全离线工作。零外部 API。只需要一个 git 仓库。 触发短语 “为什么这个代码存在”,“为什么这个被添加”,“这个的历史是什么”,“git 考古学”,“追踪这行代码”,“blame 链”,“为什么这个神奇数字在这里”,“谁添加了这个并且为什么”,“解释这个文件的历史”,“神秘代码”,“未解释的块”,“/git-blame-archaeologist” 如何提供输入 # 选项 1:调查特定行 /git-blame-archaeologist src/auth/middleware.ts:47 # 选项 2:调查行范围 /git-blame-archaeologist src/config.py:120-135 # 选项 3:调查命名符号(函数、常量) /git-blame-archaeologist --symbol TIMEOUT_MS src/ # 选项 4:调查文件的整个最近历史 /git-blame-archaeologist src/api/users.ts # 选项 5:在文件中找到所有“神秘块”(terse 提交消息) /git-blame-archaeologist --find-mysteries src/ # 选项 6:从特定提交开始并追踪回去 /git-blame-archaeologist src/utils.js:88 --since abc1234 步骤 1:运行 git blame # 获取特定行或文件的 blame git blame -L 47,47 src/auth/middleware.ts --porcelain # -L:行范围 # --porcelain:机器可读输出,包含完整的提交哈希 # 对于行范围 git blame -L 120,135 src/config.py --porcelain # 对于整个文件(condensed) git blame --date=short src/api/users.ts 读取 blame 输出: # porcelain 格式:abc1234def5678... 47 47 作者 Alice Chen 作者邮件 作者时间 1741824000 作者时区 +0800 提交者 Alice Chen 提交时间 1741824000 摘要 修复超时问题 文件名 src/auth/middleware.ts const TIMEOUT = 47000 要提取的关键字段: 摘要 —— 提交消息(通常很简短) 提交哈希(abc1234...)—— 使用它来获取完整的上下文 作者时间 —— 何时修改 步骤 2:获取完整的提交上下文 # 获取完整的提交消息和 diff,用于被责怪的提交 COMMIT_HASH="abc1234def5678" # 完整的提交,包含 diff 上下文,用于更改的行 git show $COMMIT_HASH --stat # 对于这个文件的具体更改 git show $COMMIT_HASH -- src/auth/middleware.ts # 检查这个提交是否引用了 PR、issue 或票据 git log --format="%H %s %b" $COMMIT_HASH -1 # 查找:“fixes #123”,“closes #456”,“JIRA-789”,“PR #234” 步骤 3:追踪重命名/移动历史 文件会被重命名、移动和分割。git blame 只显示当前路径的历史,仅在最后一次重命名之后。 # 跟踪文件的重命名 git log --follow --all --oneline -- src/auth/middleware.ts # --follow:追踪重命名 # --all:包括所有分支 # 找到原始文件名 git log --follow --diff-filter=R --summary -- src/auth/middleware.ts | grep "rename" # 显示:“rename old/path/auth.js => src/auth/middleware.ts (95%)” # 如果重命名,也对旧路径进行 blame,以获取完整的历史 git log --follow -p -- src/auth/middleware.ts | grep -A5 "TIMEOUT = " 步骤 4:重构决策时间线 import subprocess import re from datetime import datetime def get_blame_for_line(filepath, line_num): """获取特定行的 git blame 数据。""" result = subprocess.run( ['git', 'blame', '-L', f'{line_num},{line_num}', '--porcelain', filepath], capture_output=True, text=True ) if result.returncode != 0: return None output = result.stdout commit_hash = output.split('\n')[0].split(' ')[0] fields = {} for line in output.split('\n'): if line.startswith('author '): fields['author'] = line[7:] elif line.startswith('author-time '): ts = int(line[12:]) fields['date'] = datetime.fromtimestamp(ts).strftime('%Y-%m-%d') elif line.startswith('summary '): fields['summary'] = line[8:] elif line.startswith('filename '): fields['filename'] = line[9:] return {'hash': commit_hash[:8], **fields} def get_full_commit_context(commit_hash, filepath): """获取完整的提交消息和链接的引用。""" result = subprocess.run( ['git', 'log', '--format=%H%n%s%n%b', '-1', commit_hash], capture_output=True, text=True ) full_message = result.stdout # 提取票据/issue 引用 refs = [] patterns = [ (r'#(\d+)', 'GitHub Issue/PR'), (r'[A-Z]+-\d+', 'Jira/Linear 票据'), (r'fixes?\s+#(\d+)', '修复 issue'), (r'closes?\s+#(\d+)', '关闭 issue'), (r'https?://[^\s]+/(?:issues?|pull)s?/(\d+)', '链接 URL'), ] for pattern, label in patterns: for m in re.finditer(pattern, full_message, re.IGNORECASE): refs.append