Tomas Vondra 偶尔会暂停写代码,转而分析自己感兴趣的数据。这次,他把目光投向 PostgreSQL 项目的开发活动,用一组图表和简短评论观察趋势、量化预期影响。
这是一种值得借鉴的工程习惯:与其凭印象判断项目“最近很活跃”,不如把问题拆成可以统计的指标。不过,提供的摘要没有列出具体图表和结果,因此不能据此断言 PostgreSQL 的提交量、贡献者规模或开发效率发生了怎样的变化。我们可以借鉴这种分析方式,自己动手检查开发记录。
提交量是入口,不是生产力成绩单
观察一个项目的开发活动,可以先提出三个问题:
| 问题 | 可用指标 | 解释边界 |
|---|---|---|
| 开发节奏是否变化? | 每月提交数 | 提交拆分方式会影响数量 |
| 参与范围是否变化? | 每月不同作者数 | 不同姓名或邮箱可能属于同一人 |
| 变更规模是否变化? | 增删行数、涉及文件数 | 格式化、生成文件会放大数字 |
这些指标描述的是仓库里留下的记录,而不是全部开发工作。讨论、评审、测试和未合入的补丁,都可能不出现在提交统计里。
尤其要避免把“提交更多”直接翻译成“效率更高”。一个拆成十次提交的修改,不一定比一次提交完成的修改更复杂,也不一定更有价值。
可以这样实践:生成 PostgreSQL 的月度活动表
下面的示例不是原文使用的分析代码,而是一种可复现的实践方案。假设本机已经安装 Git 和 Python 3,我们统计当前默认分支的可达历史,按提交者时间汇总每月提交数,并按作者姓名与邮箱统计身份数。
运行前,可以修改 START_MONTH,控制输出的起始月份。首次克隆需要网络访问,也会下载较多历史数据。
git clone https://git.postgresql.org/git/postgresql.git
cd postgresql
python3 - <<'PY'
import csv
import subprocess
import sys
from collections import Counter, defaultdict
from datetime import datetime, timezone
START_MONTH = "2020-01"
result = subprocess.run(
[
"git", "log", "HEAD",
"--no-merges",
"--format=%ct%x09%an%x09%ae",
],
check=True,
capture_output=True,
text=True,
)
commits = Counter()
authors = defaultdict(set)
for line in result.stdout.splitlines():
timestamp, name, email = line.split("\t", 2)
month = datetime.fromtimestamp(
int(timestamp), tz=timezone.utc
).strftime("%Y-%m")
if month < START_MONTH:
continue
commits[month] += 1
authors[month].add((name, email.lower()))
writer = csv.writer(sys.stdout)
writer.writerow(["month", "commits", "author_identities"])
for month in sorted(commits):
writer.writerow([month, commits[month], len(authors[month])])
PY
输出可以直接保存成 CSV,再用电子表格绘制两条折线。注意,示例不会补齐完全没有提交的月份;如果分析其他仓库,应在绘图前补零,避免时间轴误导。
这里还刻意排除了合并提交,减少合并方式对提交数的影响。但这只是一个分析口径,并不是唯一正确答案。
图表出现拐点时,先检查口径
假设某个月提交数突然上升,值得继续追问,而不是立刻宣布项目“加速了”。
- 是否统计了多个分支? 使用
--all会扩大范围,维护分支上的回补可能增加提交数量。 - 是否重复计算了同一项修改? 同一个修复在多个分支落地,会留下不同的提交记录。
- 作者身份是否需要合并? 姓名、邮箱变化会使“身份数”高于实际人数。
- 时间字段是否合适? 作者时间与提交者时间回答不同问题;补丁写成和最终合入可能相隔很久。
- 当前月份是否完整? 月中数据不能直接与完整月份比较。
对于峰值月份,可以进一步检查提交内容:
git log HEAD --no-merges \
--since="2024-03-01T00:00:00Z" \
--before="2024-04-01T00:00:00Z" \
--date=iso-strict \
--format="%h %cd %s" \
--stat
把日期改成你要调查的月份。这一步的作用,是让数字回到具体修改上:峰值究竟来自许多独立改进,还是少数集中处理的变更?
把统计当作调查线索
Vondra 的做法提醒我们,开发数据分析不一定需要从复杂平台开始。一个明确的问题、一份仓库历史、一套稳定口径,就能形成有用的观察起点。
真正用于团队决策前,建议检查三件事:
- 记录统计范围:分支、时间字段、合并提交处理方式必须明确。
- 保留复现信息:保存脚本和分析时的
git rev-parse HEAD,让结果能够重新计算。 - 用内容验证解释:结合提交说明、补丁讨论和版本计划,理解曲线为什么变化。
图表最有价值的地方,不是给开发者打分,而是帮助我们发现值得进一步调查的问题。