少见的模板升级机制:full-stack-ai-agent-template的make upgrade三方合并原理深度解析
【免费下载链接】full-stack-ai-agent-templateFull-stack AI app generator — FastAPI + Next.js with AI Agents, RAG, streaming, auth, and 20+ integrations out of the box.项目地址: https://gitcode.com/gh_mirrors/fu/full-stack-ai-agent-template
full-stack-ai-agent-template 是一个开箱即用的全栈 AI 应用模板(FastAPI + Next.js,内置 AI Agent、RAG、流式对话与 20+ 集成),而它最"少见"的能力,是内置的模板升级机制:一条make upgrade命令就能把模板的新版本变更合并进你已生成的项目——通过真正的git 三方合并(3-way merge),自动更新模板改过的文件、完整保留你的自定义代码,冲突则留给你手工解决,全程可预览、可回滚。
为什么模板项目需要"模板升级"机制 🤔
普通脚手架生成完就"断联"了:模板持续迭代,你的项目只能手动追。full-stack-ai-agent-template 把升级变成了一等公民——生成项目后你随时可以跑:
make upgrade-dry-run # 预览会有什么变化(不改动任何文件) make upgrade # 真正执行升级(结果落在独立 git 分支上) make upgrade-finalize # 解决完冲突后,把版本清单升级到新版这些目标由模板生成项目时写入 Makefile(见 Makefile),底层调用的是fastapi-fullstack upgradeCLI。
三方合并的核心原理:BASE / OURS / THEIRS
整个机制的灵魂在 merge.py 中的merge_trees函数:它不自己发明合并算法,而是在一个临时 bare 仓库里调用 git 原生的merge-tree --write-tree合并引擎。合并需要三个版本的完整文件树:
| 角色 | 含义 | 从哪来 |
|---|---|---|
| BASE | 你当初生成项目时的模板版本 | 用你当年的答案重新渲染出来的 |
| OURS | 你当前的项目(含全部自定义代码) | 从你项目的 git HEAD 提取 |
| THEIRS | 目标新版本的模板 | 用你当年的答案重新渲染出来的 |
只要三个树同时存在,git 就能精确区分"哪些差异是你改的(BASE↔OURS),哪些是模板改的(BASE↔THEIRS),互不覆盖。合并结果落在专用分支template-upgrade/v<版本>上,你的主干历史和未提交内容分毫未动。
合并前的 3 个关键准备步骤
1️⃣ 用"你当年的答案"重新渲染新旧模板
关键在一个小小的清单文件.fastapi-fullstack.json(由 manifest.py 的build_manifest生成):它记录了生成时的模板版本和全部配置答案(是否开启 RAG、选哪个任务队列等),不含任何密钥,安全可提交。
有了它,工具就能把旧版模板和新版模板分别渲染(render.py 中的render_template),再对比你的项目。渲染时会用一批"空壳命令"替换 uv、ruff、bun 等外部工具调用,跳过耗时的安装步骤,只取文件结构——历史版本怎么渲染,新树就怎么渲染,保证可复现。
如果两个版本之间模板重命名了某个配置项(比如use_pgvector改名为vector_store),reconcile.py 的reconcile_context会按元数据把旧答案映射到新键名,避免合并时误判"你删掉了一堆功能"。
2️⃣ 格式归一化:消灭"假差异"
BASE、OURS、THEIRS 三棵树必须格式完全一致,否则缩进和换行差异会被误读成代码编辑。normalize.py 会在三棵树上跑同一套 ruff / Prettier(且只格式化渲染出来的树,绝不动你自己的代码),并把迁移文件里易变的生成时间戳统一抹平——这样合并引擎看到的每一处差异都是"真差异"。
3️⃣ UPGRADES.yaml:内容 diff 看不到的结构变更
文件被移动/重命名是纯内容对比的盲区(会被读成"删一个 + 加一个",导致你在旧路径上的编辑丢失)。仓库根目录的 UPGRADES.yaml 由维护者按版本记录这些事实:
renames:文件/目录迁移记录,合并前在 BASE 和 OURS 上预先搬移,让你的编辑"跟随文件到新路径";variable_renames:模板配置项改名映射;breaking/manual_steps:跨版本聚合后展示在升级报告里,例如"合并后请运行make db-upgrade"。
make upgrade 实战:预览、执行、报告
第一步永远是预览:make upgrade-dry-run只打印分组报告,不改动任何文件。确认没问题后执行make upgrade,工具会创建升级分支、应用所有安全变更,并在结尾打印精确的回滚命令。
升级报告由 report.py 渲染,把每个文件按 classify.py 的分类矩阵归组。新手只需记住这张速查表:
| 报告分组 | 含义 | 你要做什么 |
|---|---|---|
| New files / New migrations | 模板新增文件 / 新增 Alembic 迁移 | 已自动加入,迁移记得跑make db-upgrade |
| Auto-updates | 模板改了、你没改 | 已自动更新,无需处理 |
| Auto-merged | 双方都改了,但没撞行 | 已自动合并,扫一眼即可 |
| Kept your changes | 你改了、模板没改 | 原样保留你的版本 |
| Conflicts | 双方改了同一处 | 打开 IDE 三方合并编辑器手工解决 |
| Your files | 你自己新建的文件 | 永不触碰 |
| Changed migrations | 模板重写了你已运行的迁移 | 重点核对,必要时回退该文件 |
冲突解决、finalize 确认与安全回滚
冲突文件会留下标准 git 冲突标记(<<<<<<< ours/>>>>>>> theirs),用 VS Code 或 PyCharm 的三方合并编辑器解决后git add。然后运行make upgrade-finalize——它会校验当前分支正确、且没有任何未解决冲突,才把清单文件中的版本号升到目标版本(runner.py 中的run_finalize)。这个"安全网"保证清单永远不会谎报你的版本。
想放弃整个升级?升级分支本来就是隔离的,一条命令即可还原(git checkout -f 原分支 && git branch -D template-upgrade/v…,命令会在升级结束时自动打印)。另外工具对.env密钥文件、锁文件、node_modules等永不合并,.env.example这类样例文件则正常合并,确保新版新增的配置项能传达到你手里。
动手体验 🚀
克隆仓库生成一个项目即可亲手体验完整的"生成 → 自定义 → 升级"闭环:
git clone https://gitcode.com/gh_mirrors/fu/full-stack-ai-agent-template完整的操作手册(含无清单老项目的upgrade recover恢复流程、故障排查)见官方指南 docs/guides/version-upgrade.md;想看整体架构可继续读 architecture.md。
小结
full-stack-ai-agent-template 的make upgrade把"追模板更新"这件脏活变成了一次可预览、可合并、可回滚的标准 git 操作:清单文件让历史可复现,格式归一化消灭假差异,UPGRADES.yaml 补上重命名盲区,最后交给 git 三方合并引擎完成最后一公里。对于在模板上构建生产项目的团队来说,这大概是同类全栈 AI 模板里少见的"长期主义"设计。
【免费下载链接】full-stack-ai-agent-templateFull-stack AI app generator — FastAPI + Next.js with AI Agents, RAG, streaming, auth, and 20+ integrations out of the box.项目地址: https://gitcode.com/gh_mirrors/fu/full-stack-ai-agent-template
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考