不能把 .ipynb 文件直接提交给普通代码文件 Git,因其 JSON 结构含 outputs、execution_count 动态字段等,导致无意义 diff 和合并冲突;应使用 nbstripout 清理后提交,并辅以 jupyterlab-git 提高操作效率。
直接得出结论:不能 .ipynb 文件直接扔进普通代码文件 Git —— 否则,每个操作单元格都会触发大量的无意义 diff,合并冲突频发,团队合作几乎瘫痪。真正可行的计划是「保持完整的开发状态 Notebook,提交态度只留纯代码结构」,依靠工具链自动转换。
因为 .ipynb 是 JSON 格式,包含 outputs、execution_count、metadata 等待动态字段。即使只有 rerun 一个 cell,Git 整个文件被重写。
- 执行一次
plt.plot(x, y)→outputs字段新增 base64 图像数据 → diff 出几百行 - 更改一行代码,但没有清空输出 → Git 记录了“代码+旧图+新图”的混合变化
- 两人同时编辑同一个 notebook → JSON 由于结构上的微小差异 merge conflict 无法自动解决
nbstripout 是专为 Jupyter 设计的 Git 过滤器,它在 commit 在此之前自动剥离非代码内容,确保 Git 只看到你真正改变的逻辑。
- 安装和启用:
pip install nbstripout && nbstripout --install - 其默认移除:
outputs、execution_count、metadata.widgets、metadata.language_info - 生效范围仅限于当前仓库(
.git/config中写入 clean/smudge 规则) - ⚠️ 注:必须在所有合作机器上运行
nbstripout --install,否则,如果有人漏装,带就会输出。 notebook 提交,污染整个历史
但不要指望它解决 diff 问题 —— 它只是把 git status、git add、git commit 搬进 JupyterLab 界面、底层或系统 Git。其价值在于降低操作门槛,特别适合不熟悉命令线的数据科学家。
Git
程序猿必备版控制工具
下载- 安装:
pip install jupyterlab-git && jupyter labextension install @jupyterlab/git - 重启后左侧出现 Git 可以直观地看到面板 modified/untracked 一键临时存储和填写文件 message 提交
- 但它不干预
.ipynb内容 —— 如果没配nbstripout,在界面上看到的 diff 依然满屏 JSON - 真正省心的组合是:
nbstripout处理内容 +jupyterlab-git处理操作流
Git 管理不是“结果”,而是“可复制过程”。把 loss 曲线、指标表、模型权重等产出全塞进去 notebook,相当于将实验报告和实验记录混合在一起。
- 训练中用
tensorboard或wandb单独记录指标,生成独立events.out.tfevents或云端链接 - 关键值导出为
metrics.json或results.csv,这种纯文本文件 Git 天然友好 - 图表用
plt.savefig("loss.png")单独保存,加进.gitignore或按需提交(如最终版对比图) - notebook 只留下:数据加载逻辑、模型定义、训练循环骨架、少量验证代码 —— 都是可复制的源代码
最常被忽视的一点:清洁不是一次性动作。只要 notebook 如果仍在本地打开和运行,输出可能会悄然积累;每次提交前必须确认 git status 显示的变化是否真的只包含代码变化 —— 不要依赖插件界面,自己跑一遍 git diff 最可靠。