Git 仓库发布历史追踪新思路
Maybe a better way to track the release history of a Git repo
在 ZipRecruiter 工作期间,我们的 Git monorepo 因部署工具为每次发布创建大量 tag 对象而陷入性能瓶颈。成千上万个 refs 导致 `packed-refs` 文件臃肿,使得日常 Git 操作显著变慢,且命令行输出杂乱无章。我提出了一种替代方案:不再为每次发布创建新 ref,而是利用 Git 自身的历史机制,通过双父 commit 构建链表来记录发布轨迹。每个应用环境仅需维护一个 ref,指向最新的元信息 commit,旧版本则通过链表回溯。这种方法不仅解决了性能问题,还让 `git log` 等原生命令能直接高效地查询发布历史,完美契合 Git 的设计哲学。
Git 专为处理成千上万个提交而设计,却不擅长处理成千上万个 refs。
- duesabati
发布(Release)和部署(Deployment)应该分开。生产环境和其他环境运行的代码之间应该几乎没有区别。不要为每个环境创建单独的发布版本,而应该用易于理解的标签(例如版本号)标记你的代码,从该版本的代码生成制品,然后在部署时决定(无论是手动还是通过自动化逻辑)使用哪个版本的代码。理想情况下,生产环境与其他环境在运行时的所有“差异”都应该在运行时定义,即通过环境变量(即使是通常在建时生成的前端内容,也应该有运行时机制来避免这种情况)。这样你的行为会更加可预测,也更容易推理。此外,你可以将构建和部署流水线在物理上分离,从而在切换到所需内容时拥有更大的灵活性。这也更容易让人(以及 LLM)清晰地看到步骤并修复 CI 流水线的问题。
如果你确实需要构建时的差异,那么你应该根据差异本身来识别它,而不是根据你假设它将在哪个环境运行来识别,因为显式永远优于隐式,尤其是对 LLM 和新开发者而言。
- turboponyy
> 在我看来,在仓库中记录部署历史似乎是合理的
这在我看来并不合理。你是在用 Git 处理那些与源代码管理没有直接关系的持久化问题。
你只需要存储“环境 X 在 1970-01-01T00:00:00Z 部署了提交 a1b2c3d”这一条信息,我不明白为什么要在仓库本身中做这件事。提交 a1b2c3d 的存在与否,与它在何时何地部署无关。
把这类数据存在负责部署的工具里吧。