保护稳定的代码版本
当模型训练脚本达到一个满意状态后,应该通过提交将其固化在仓库历史中。Git 的提交操作会为当前文件集合创建一个快照,后续所有修改都基于此快照进行。
执行以下命令完成提交:
sql
git add .
git commit -m "baseline model with val_acc 0.92"
此后若想丢弃工作区中所有未提交的修改,恢复到这次提交的状态,可以使用:
erlang
git restore .
如果需要同时丢弃暂存区里的内容,直接重置到最新提交:
css
git reset --hard HEAD
对于重要的里程碑版本,可以添加标签以方便日后查找:
git tag v1.0
通过 git checkout v1.0 即可切换到该版本进行查看。
只要代码被提交过,就不会被真正丢失。即使后续通过重置或删除分支等方式移除了引用,也可以通过 git reflog 找回。
可以随时切会主分支
arduino
git switch master
在独立分支上进行实验
开发新功能或尝试不同模型结构时,应该从主分支创建新分支,在分支上进行修改,避免影响主分支的稳定性。
从当前主分支( master)创建并切换到一个新分支:
r
git switch -c try_vit
此时终端会显示当前分支名已变为 try_vit。接下来所有的修改和提交都只记录在该分支上。
在实验分支上建议频繁提交,记录每一步尝试:
sql
git add model.py
git commit -m "change backbone to ViT-B/16"
此时主分支指针停留在创建分支时的提交,而实验分支指针已向前移动,两者相互独立。
如果实验分支上的修改不理想,可以切换回主分支并删除实验分支:
arduino
git switch master
git branch -D try_vit
切换回 master 后,工作目录文件会恢复为 master 分支最新提交的状态,实验分支的修改不再可见。删除分支只是移除了指向提交的指针,未引用的提交对象会在垃圾回收时被清理。
分支切换的原理
Git 的提交对象通过哈希链组织成历史图。分支名是指向某个提交的指针,HEAD 指针则指向当前所在的分支。切换分支时,Git 会移动 HEAD 指针到目标分支,同时将工作目录的文件内容替换为目标分支所指向提交的快照。
如果切换前工作目录有未提交的修改,Git 会检查这些修改是否与目标分支的文件冲突。若冲突则拒绝切换,提示先暂存或提交修改。因此切换分支前通常先执行 git status 确认工作区干净。
忽略大文件、二进制文件
机器学习项目常包含大量数据集文件和训练权重文件,这些文件体积大且不适合由 Git 管理。应当通过 .gitignore 文件将它们排除在版本控制之外。
编写 .gitignore 文件
在项目根目录创建 .gitignore,按以下方式编写:
markdown
data/
datasets/
*.pt
*.pth
*.ckpt
*.h5
*.pb
*.onnx
logs/
wandb/
__pycache__/
*.pyc
- 以斜杠结尾的路径表示目录,会忽略该目录下所有内容。
- 以星号开头的模式匹配文件扩展名。
保存后,未追踪的文件中符合这些模式的内容不会再出现在 git status 的输出里。
仅追踪特定文件类型
如果需要让仓库只追踪 .py 和 .yaml 文件,可以采用白名单方式:
diff
/*
!.gitignore
!*.py
!*.yaml
这里先忽略所有内容,再将 .gitignore 自身、.py 和 .yaml 文件排除出忽略规则。但需要注意,如果 .py 文件位于子目录,而该子目录被根目录的 /* 规则忽略,则文件本身也无法被恢复追踪。因此需要额外释放子目录:
diff
/*
!.gitignore
!src/
src/*
!src/*.py
此方法维护成本较高。更实用的做法是组织好项目结构,将需要追踪的代码和配置文件集中放在特定目录(如 src/、configs/),然后在 .gitignore 中只忽略明显的大文件目录:
kotlin
data/
weights/
*.pth
*.ckpt
这样无需复杂的白名单规则,Git 会正常追踪 src/ 和 configs/ 内的所有文件。
处理已追踪的大文件
如果大文件已经通过 git add 加入仓库,仅修改 .gitignore 不会使其被忽略。需要先用 git rm --cached 将它们从索引中移除,同时保留本地文件:
bash
git rm -r --cached data/
git rm --cached weights/best.pt
git commit -m "stop tracking large files"
注意,其他协作者在拉取这次提交时,会删除本地对应的文件,因为 Git 认为这些文件不再属于仓库。在执行前应与团队沟通或让成员备份文件。
如果大文件已推送至远程仓库并记录在历史中,仓库体积不会因为新的提交而减小。要彻底清除,需要使用 git filter-branch 或 BFG Repo-Cleaner 等工具重写历史,这一操作风险较高,需要确认团队可接受并做好备份。对于大型文件,更好的实践是使用 Git LFS 或外部存储,在 README 中说明下载方式。