engineering-retro

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Engineering Retrospective

工程回顾

Generate a structured, git-based engineering retrospective for a configurable time window. This is a read-only analysis — no files are modified except the optional JSON snapshot.
针对可配置的时间窗口生成结构化的、基于Git的工程回顾报告。这是一项只读分析——除可选的JSON快照外,不会修改任何文件。

Arguments

参数

/engineering-retro [TIME_WINDOW] [PATH_SCOPE]
  • TIME_WINDOW (optional):
    24h
    ,
    7d
    (default),
    14d
    ,
    30d
  • PATH_SCOPE (optional): restrict analysis to a subdirectory (monorepo support), e.g.
    services/api
Examples:
  • /engineering-retro
    — last 7 days, full repo
  • /engineering-retro 30d
    — last 30 days, full repo
  • /engineering-retro 14d services/api
    — last 14 days, scoped to
    services/api/
/engineering-retro [TIME_WINDOW] [PATH_SCOPE]
  • TIME_WINDOW(可选):
    24h
    7d
    (默认)、
    14d
    30d
  • PATH_SCOPE(可选):将分析范围限制到子目录(支持monorepo),例如
    services/api
示例:
  • /engineering-retro
    —— 最近7天,全仓库
  • /engineering-retro 30d
    —— 最近30天,全仓库
  • /engineering-retro 14d services/api
    —— 最近14天,范围限定为
    services/api/

Execution Steps

执行步骤

Step 1: Environment Detection

步骤1:环境检测

Detect runtime context before any analysis:
bash
undefined
在进行任何分析前先检测运行时上下文:
bash
undefined

Default branch

默认分支

DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@') if [ -z "$DEFAULT_BRANCH" ]; then DEFAULT_BRANCH=$(git remote show origin 2>/dev/null | grep 'HEAD branch' | awk '{print $NF}') fi
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@') if [ -z "$DEFAULT_BRANCH" ]; then DEFAULT_BRANCH=$(git remote show origin 2>/dev/null | grep 'HEAD branch' | awk '{print $NF}') fi

System timezone

系统时区

TZ_NAME=$(date +%Z)
TZ_NAME=$(date +%Z)

Time window — convert argument to --since format

时间窗口 —— 将参数转换为 --since 格式

24h → "24 hours ago", 7d → "7 days ago", 14d → "14 days ago", 30d → "30 days ago"

24h → "24 hours ago", 7d → "7 days ago", 14d → "14 days ago", 30d → "30 days ago"


If `DEFAULT_BRANCH` detection fails, abort with an error — do not guess.

如果`DEFAULT_BRANCH`检测失败,则终止并报错——请勿猜测。

Step 2: Gather Raw Git Data

步骤2:收集原始Git数据

Collect commits within the time window on the detected default branch:
bash
undefined
收集检测到的默认分支在时间窗口内的提交记录:
bash
undefined

All commits in window (with optional path scope)

时间窗口内的所有提交(含可选路径范围)

git log origin/$DEFAULT_BRANCH --since="$SINCE" --format="%H|%aI|%aN|%s" -- $PATH_SCOPE
git log origin/$DEFAULT_BRANCH --since="$SINCE" --format="%H|%aI|%aN|%s" -- $PATH_SCOPE

Diff stats for the window

时间窗口内的差异统计

git log origin/$DEFAULT_BRANCH --since="$SINCE" --numstat --format="%H" -- $PATH_SCOPE

Capture: commit hash, author date (ISO), author name, subject line, files changed, insertions, deletions.
git log origin/$DEFAULT_BRANCH --since="$SINCE" --numstat --format="%H" -- $PATH_SCOPE

捕获信息:提交哈希、作者日期(ISO格式)、作者姓名、提交主题、修改文件、新增行数、删除行数。

Step 3: Compute Aggregate Metrics

步骤3:计算聚合指标

From the raw data, compute:
  • Total commits in window
  • Unique contributors (distinct author names)
  • Files changed (unique file paths across all commits)
  • Lines added (sum of insertions)
  • Lines removed (sum of deletions)
  • Net delta (added - removed)
  • Avg commit size (total lines changed / total commits)
从原始数据中计算:
  • 时间窗口内的总提交数
  • 唯一贡献者(不同作者姓名)
  • 修改文件数(所有提交中唯一的文件路径)
  • 新增行数(新增行数总和)
  • 删除行数(删除行数总和)
  • 净变化量(新增行数 - 删除行数)
  • 平均提交大小(总修改行数 / 总提交数)

Step 4: Time Distribution

步骤4:时间分布分析

Analyze commit timestamps (converted to system timezone
$TZ_NAME
):
  • Commits by day of week: Mon-Sun histogram
  • Commits by hour: 0-23 histogram
  • Peak day: day with most commits
  • Peak hours: hours with most activity
Present as a compact text histogram.
分析提交时间戳(转换为系统时区
$TZ_NAME
):
  • 按星期几分布的提交数:周一至周日的直方图
  • 按小时分布的提交数:0-23点的直方图
  • 峰值日期:提交数最多的日期
  • 峰值时段:活动最频繁的时段
以紧凑的文本直方图形式呈现。

Step 5: Session Analysis

步骤5:会话分析

Group commits into work sessions using a >2 hour gap as a session boundary:
  1. Sort commits by author and timestamp
  2. For each author, iterate chronologically — if gap between consecutive commits exceeds 2 hours, start a new session
  3. Compute per-session: duration (first commit to last commit), commit count
  4. Aggregate: total sessions, average session length, longest session, average commits per session
Sessions with a single commit get a default duration of 0 (point-in-time).
以超过2小时的间隔作为会话边界,将提交记录分组为工作会话:
  1. 按作者和时间戳对提交记录排序
  2. 对每位作者按时间顺序遍历——如果连续提交间隔超过2小时,则开启新会话
  3. 计算每个会话的:时长(从第一个提交到最后一个提交)、提交数
  4. 聚合统计:总会话数、平均会话时长、最长会话时长、平均每会话提交数
仅包含单个提交的会话默认时长为0(即时提交)。

Step 6: Commit Type Classification

步骤6:提交类型分类

Classify each commit using conventional commit prefixes from the subject line:
Prefix patternCategory
feat:
,
feat(
feature
fix:
,
fix(
,
bugfix
fix
refactor:
,
refactor(
refactor
chore:
,
chore(
,
build:
,
ci:
chore
docs:
,
doc:
docs
test:
,
tests:
test
perf:
perf
style:
style
For commits without conventional prefixes, apply diff heuristics:
  • Primarily new files added → feature
  • Primarily deletions → refactor
  • Test files only → test
  • Config/CI files only → chore
  • Documentation files only → docs
  • Otherwise → uncategorized
Report counts and percentages per category.
根据提交主题行中的约定式提交前缀对每个提交进行分类:
前缀模式分类
feat:
,
feat(
feature
fix:
,
fix(
,
bugfix
fix
refactor:
,
refactor(
refactor
chore:
,
chore(
,
build:
,
ci:
chore
docs:
,
doc:
docs
test:
,
tests:
test
perf:
perf
style:
style
对于没有约定式前缀的提交,应用差异启发式规则:
  • 主要为新增文件 → feature
  • 主要为删除内容 → refactor
  • 仅修改测试文件 → test
  • 仅修改配置/CI文件 → chore
  • 仅修改文档文件 → docs
  • 其他 → 未分类
报告各分类的提交数及占比。

Step 7: Hotspot Analysis

步骤7:热点分析

Identify the top 10 most-modified files by number of commits touching them:
bash
git log origin/$DEFAULT_BRANCH --since="$SINCE" --name-only --format="" -- $PATH_SCOPE | sort | uniq -c | sort -rn | head -20
Flag any file modified in >50% of total commits as a hotspot. Hotspots indicate:
  • Active area of development (expected during feature work)
  • Potential coupling issues (if unrelated commits keep touching the same file)
  • Possible need for decomposition (if the file is large)
找出被修改次数最多的前10个文件(按涉及的提交数统计):
bash
git log origin/$DEFAULT_BRANCH --since="$SINCE" --name-only --format="" -- $PATH_SCOPE | sort | uniq -c | sort -rn | head -20
将在超过50%的总提交中被修改的文件标记为热点文件。热点文件表明:
  • 活跃的开发领域(功能开发期间属于正常情况)
  • 潜在的耦合问题(如果无关提交频繁修改同一文件)
  • 可能需要拆分(如果文件过大)

Step 8: PR Analysis

步骤8:PR分析

If the remote is GitHub (check
git remote get-url origin
for
github.com
):
bash
undefined
如果远程仓库是GitHub(通过
git remote get-url origin
检查是否包含
github.com
):
bash
undefined

Merged PRs in window

时间窗口内合并的PR

gh pr list --state merged --base $DEFAULT_BRANCH --search "merged:>=$SINCE_DATE" --json number,title,author,mergedAt,additions,deletions,changedFiles,reviews

Compute:

- **Total merged PRs**
- **Size distribution**: S (<50 lines), M (50-200), L (200-500), XL (>500)
- **Review turnaround**: time from PR creation to first review (median, p90)
- **Merge turnaround**: time from PR creation to merge (median, p90)

If not a GitHub remote or `gh` is unavailable, skip this step and note it in the output.
gh pr list --state merged --base $DEFAULT_BRANCH --search "merged:>=$SINCE_DATE" --json number,title,author,mergedAt,additions,deletions,changedFiles,reviews

计算:

- **合并PR总数**
- **大小分布**:S(<50行)、M(50-200行)、L(200-500行)、XL(>500行)
- **审核周转时间**:从PR创建到首次审核的时间(中位数、90分位数)
- **合并周转时间**:从PR创建到合并的时间(中位数、90分位数)

如果不是GitHub远程仓库或`gh`不可用,则跳过此步骤并在输出中说明。

Step 9: Focus Score

步骤9:专注度得分

Compute the ratio of focused commits (touching 3 or fewer files) to total commits:
focus_score = commits_touching_le_3_files / total_commits
Interpretation:
  • >0.8: highly focused, small incremental changes
  • 0.5-0.8: moderate focus, mix of targeted and broad changes
  • <0.5: broad changes dominating, may indicate large refactors or low commit discipline
计算聚焦提交(修改3个或更少文件)占总提交数的比例:
focus_score = commits_touching_le_3_files / total_commits
解读:
  • >0.8:高度聚焦,小增量修改
  • 0.5-0.8:中等聚焦,混合针对性和宽泛修改
  • <0.5:宽泛修改占主导,可能表明大型重构或提交规范不足

Step 10: Per-Author Breakdown

步骤10:按作者细分

For each contributor, report:
  • Commit count
  • Lines added / removed
  • Top 3 most-touched files
  • Primary commit types (from Step 6)
  • Number of sessions and average session length (from Step 5)
Frame this as contributor highlights — recognition of work done, not a ranking or performance metric. Order alphabetically by author name.
针对每位贡献者,报告:
  • 提交数
  • 新增/删除行数
  • 最常修改的前3个文件
  • 主要提交类型(来自步骤6)
  • 会话数和平均会话时长(来自步骤5)
将此作为贡献者亮点——认可完成的工作,而非排名或绩效指标。按作者姓名字母顺序排列。

Step 11: Week-over-Week Comparison

步骤11:周环比对比

Check for a prior snapshot in
.engineering-retros/
:
  • Find the most recent
    *.json
    file
  • If it exists and covers the adjacent prior window, compute deltas:
    • Commit count delta (%)
    • Lines changed delta (%)
    • Contributor count delta
    • Focus score delta
    • Category distribution shift
If no prior snapshot exists, note this is the first retrospective and skip comparison.
检查
.engineering-retros/
目录中是否存在历史快照:
  • 查找最新的
    *.json
    文件
  • 如果存在且覆盖相邻的前一个时间窗口,则计算变化量:
    • 提交数变化(百分比)
    • 修改行数变化(百分比)
    • 贡献者数量变化
    • 专注度得分变化
    • 分类分布变化
如果没有历史快照,则说明这是首次回顾并跳过对比。

Step 12: Save Snapshot

步骤12:保存快照

Save a JSON snapshot for future comparisons:
.engineering-retros/<YYYY-MM-DD>.json
Schema:
json
{
  "date": "YYYY-MM-DD",
  "window": "7d",
  "path_scope": null,
  "branch": "main",
  "timezone": "PST",
  "metrics": {
    "commits": 0,
    "contributors": 0,
    "files_changed": 0,
    "lines_added": 0,
    "lines_removed": 0,
    "net_delta": 0,
    "focus_score": 0.0
  },
  "categories": {},
  "hotspots": [],
  "sessions": {
    "total": 0,
    "avg_length_minutes": 0
  },
  "authors": {},
  "pr_stats": null
}
Create the
.engineering-retros/
directory if it does not exist. Ensure
.engineering-retros/
is in
.gitignore
(add it if missing — this is the one permitted file modification).
保存JSON快照用于未来对比:
.engineering-retros/<YYYY-MM-DD>.json
Schema:
json
{
  "date": "YYYY-MM-DD",
  "window": "7d",
  "path_scope": null,
  "branch": "main",
  "timezone": "PST",
  "metrics": {
    "commits": 0,
    "contributors": 0,
    "files_changed": 0,
    "lines_added": 0,
    "lines_removed": 0,
    "net_delta": 0,
    "focus_score": 0.0
  },
  "categories": {},
  "hotspots": [],
  "sessions": {
    "total": 0,
    "avg_length_minutes": 0
  },
  "authors": {},
  "pr_stats": null
}
如果
.engineering-retros/
目录不存在则创建。确保
.engineering-retros/
.gitignore
中(如果缺失则添加——这是唯一允许修改的文件)。

Step 13: Generate Narrative Summary

步骤13:生成叙事性总结

Produce the final output in this structure:

Engineering Retrospective — [DATE_RANGE] ([TIMEZONE]) Branch: [DEFAULT_BRANCH] | Scope: [PATH_SCOPE or "full repo"]
按以下结构生成最终输出:

工程回顾 —— [日期范围]([时区]) 分支: [DEFAULT_BRANCH] | 范围: [PATH_SCOPE 或 "全仓库"]

Metrics

核心指标

  • Commits: N | Contributors: N | Files changed: N
  • Lines: +N / -N (net: +/-N)
  • Avg commit size: N lines | Focus score: N.NN
  • 提交数:N | 贡献者数:N | 修改文件数:N
  • 行数:+N / -N(净变化:+/-N)
  • 平均提交大小:N行 | 专注度得分:N.NN

Time Patterns

时间模式

  • Peak day: [DAY] | Peak hours: [RANGE]
  • [compact histogram]
  • Sessions: N total | Avg length: Nm | Longest: Nm
  • 峰值日期:[星期] | 峰值时段:[时间段]
  • [紧凑直方图]
  • 会话数:N个 | 平均时长:N分钟 | 最长会话:N分钟

Work Breakdown

工作细分

  • [category]: N commits (NN%)
  • ...
  • [分类]:N次提交(NN%)
  • ...

Hotspots

热点文件

  • path/to/file
    — N commits [HOTSPOT if >50%]
  • ...
  • path/to/file
    —— N次提交 [如果占比>50%则标记为HOTSPOT]
  • ...

Contributor Highlights

贡献者亮点

  • [Author]: N commits, +N/-N lines, focused on [top files], primarily [categories]
  • ...
  • [作者]:N次提交,+N/-N行,专注于[高频修改文件],主要提交类型为[分类]
  • ...

PR Summary (if available)

PR总结(若可用)

  • Merged: N | Size dist: S/M/L/XL | Median review turnaround: Xh
  • 合并数:N | 大小分布:S/M/L/XL | 中位数审核周转时间:X小时

Week-over-Week (if available)

周环比对比(若可用)

  • Commits: +/-N% | Lines: +/-N% | Focus: +/-N.NN
  • 提交数:+/-N% | 行数:+/-N% | 专注度得分:+/-N.NN

Observations

观察结论

  • [2-4 bullet points identifying patterns, achievements, and areas worth attention]
  • Based on data only — no speculation about intent or quality judgments about individuals

  • [2-4个要点,识别模式、成果和值得关注的领域]
  • 仅基于数据——不推测意图,不对个人做出质量判断

Constraints

约束条件

  • Read-only: no code modifications, no branch changes, no git operations that alter state
  • No hardcoded timezone: always detect from
    date +%Z
  • No hardcoded branch: always detect dynamically via
    git symbolic-ref
    or
    git remote show
  • No individual performance judgments: author breakdown is for recognition, not evaluation
  • Path scope respected: all git commands must include
    -- $PATH_SCOPE
    when a scope is provided
  • Snapshot storage:
    .engineering-retros/
    only, never
    .context/retros/
  • 只读:不修改代码,不切换分支,不执行任何会改变状态的Git操作
  • 无硬编码时区:始终通过
    date +%Z
    检测
  • 无硬编码分支:始终通过
    git symbolic-ref
    git remote show
    动态检测
  • 不做个人绩效判断:作者细分仅用于认可工作,而非评估
  • 严格遵循路径范围:当指定范围时,所有Git命令必须包含
    -- $PATH_SCOPE
  • 快照存储:仅存储在
    .engineering-retros/
    ,绝不存储在
    .context/retros/