Hotdry.
systems-engineering

使用 git fast-import 从快照重建 44 年 Unix 历史 Git 仓库

基于 Spinellis 项目,手把手重建 Unix 历史 repo:合成 commits,支持 blame 和 diffs 进行历时代码分析,提供参数清单。

Unix 系统的演化跨越半个世纪,从 1970 年的 PDP-7 小型汇编内核,到如今 FreeBSD 的数千万行代码,其代码脉络分析一直是软件考古学的难题。传统快照难以追踪函数归属和变更历史,而通过 git fast-import 合成连续 commits,能让 git blame/log/diff 等工具无缝工作,实现 diachronic(历时)代码分析。本文聚焦单一技术点:如何从 24 个历史快照(Bell Labs V1-V7、BSD 系列、386BSD、FreeBSD)重建 1.5GB、50 万 commits 的 Git 仓库,提供可落地命令清单、参数阈值和监控要点。

重建价值与事实支撑

合成仓库让 git blame 能追溯代码行作者,如 pipe.c 中 Ken Thompson 1974 年代码仍可见于现代 FreeBSD。这基于文件 mod time 排序生成 commits,并通过作者映射文件(author-path/*.map)归属 90%+ 文件。证据显示,仓库包含 2300+ merges,如 BSD-3 从 32V 和 V6 合并,支持真实 blame 传播。“The repository employs the commonly used Git system for its storage, and is hosted on the popular GitHub archive.” Spinellis 项目已验证跨 44 年连续时间线,适用于研究代码长寿(如 V7 timezone.c 存活至今)和演化模式(如 goto 使用率从高到零)。

准备环境(清单 1)

  1. 依赖安装:Git、Perl、VCS::SCCS、Git::FastExport(cpanm VCS::SCCS Git::FastExport)。Linux 下需 libbsd-dev 编译旧 patch。
  2. 克隆工具git clone https://github.com/dspinellis/unix-history-make
  3. 下载快照cd unix-history-make; make fetch(~11GB,包括 TUHS 存档、CSRG CD、386BSD 软盘)。
    • 阈值:磁盘 >20GB(临时),网络 >100Mbps 避免超时。
  4. 验证 FS:case-sensitive(如 ext4),避 NTFS/HFS 默认(丢文件)。
  5. 创建空 repomkdir ../unix-history; cd ../unix-history; git init; git checkout -b main

核心合成流程(清单 2,可自动化)

unix-history-make 的 Makefile 封装全过程:make(~ 数小时,视 CPU)。手动示例导入 Bell 32V:

perl ../unix-history-make/import-dir.pl -v -m Research-V7 -c ../author-path/Bell-32V \
  -n ../bell.au -r Research-V7 -i ../ignore/Bell-32V \
  $ARCHIVE/32v "Bell 32V" -0500 | git fast-import --force
  • 参数详解
    参数 值示例 作用 & 阈值
    -m Research-V7 父 commit/tag,必填,避免孤立历史
    -c ../author-path/Bell-32V 路径正则→作者 ID,覆盖 90% 文件
    -n ../bell.au ID→姓名 / 邮件(如 research!ken),UUCP 格式真实
    -r Research-V7 引用分支,合成 merge
    -i ../ignore/Bell-32V 忽略元数据文件,防假 timestamp
    时区 -0500 EST,文件 mod time +5h 偏移
    git fast-import --force 覆盖重复,避免中断;--stats 监控进度

全流程:按时间序 import 27 来源(快照 + SCCS/CVS/Git),每个快照移至 .ref 隐藏目录(blame 穿透),打 tag(如 Research-V1)。SCCS 导入用 VCS::SCCS,FreeBSD CVS 先 cvs2git 转 Git。

优化后:git reflog expire --expire=now --all; git gc --aggressive 压缩至 1.5GB。

分析应用 & 监控(清单 3)

重建后克隆验证:git clone https://github.com/dspinellis/unix-history-repo; git checkout BSD-Release

  1. blame 示例git blame -C -C sys/pipe.c
    • 输出:显示 Thompson 1974 行,Joy 1980 注释。阈值:>85% 行有具体作者(unmatched/ 查缺)。
  2. diff 跨版git diff Research-V1..FreeBSD-12 sys/sched.c 调度器演化。
  3. log 追踪git log --follow --reverse --date-order -- usr/src/cmd/c/c00.c C 编译器变更史。
  4. 监控点
    指标 预期阈值 命令
    commits ~500k git rev-list --count HEAD
    merges >2k git rev-list --merges --count HEAD
    blame 覆盖 >90% 采样 10 文件,grep 非 default 作者
    大小 <2GB du -sh .git
    tags 完整 100+ git tag | wc -l

异常:blame 低 → 补 author-path;merge 错 → 查 bsd-family-tree。

风险 & 回滚策略

  • 风险 1:合成非真 VCS,timestamp 依赖快照准确(OCR V1 内核有噪)。回滚:shallow clone --depth 100 先验验。
  • 风险 2:repo 自动重建变异,fork 存档。
  • 风险 3:大 repo 慢,设 core.preloadindex=true; pack.threads=8 加速。 测试:30+ 自动化 test(Makefile),比对 tag vs 原快照。

通过此技术,开发者可参数化重建类似历史 repo,用于内核考古或长期项目分析。参数如作者映射阈值(正则优先级)、import 批次(<1000 commits / 批防 OOM)确保可落地。

资料来源

  • GitHub: dspinellis/unix-history-make, unix-history-repo
  • Spinellis, "A repository with 44 years of Unix evolution", MSR 2015.

(正文 1256 字)

查看归档