Git 代码丢失与恢复 — 复盘记录
日期:2026-06-09
涉及文件:portfolio/algo/manager_factory.py
涉及 commit:0cc6e24(master 分支)
一、问题描述
commit 0cc6e24("ETF200个标的组合,增加管理人00401etf")在 master 分支上添加了管理人 00401_etf 的完整配置,包括:
_weight_RP5— 5 天权重窗口_en_MTteste— 风筹引擎参数_m_e0401_test— 管理人配置@register("管理人00401")/@register("管理人00401_etf")— 注册
但 merge dev → master 后,这些代码全部丢失。
二、根因分析
2.1 事件时间线
| 时间 | 操作 | 分支 | 说明 |
|---|---|---|---|
| T1 | 在 master 上 commit 0cc6e24 | master | 添加 00401_etf 配置 |
| T2 | 创建 dev 分支 | dev | 从 master 检出 |
| T3 | stash 本地修改 | master | 修改了 plan_bt.py, etf_demo.py, fof_demo_20.py |
| T4 | checkout dev | dev | 切换到 dev |
| T5 | stash pop | dev | 恢复修改,产生冲突 |
| T6 | 解决冲突 — etf_demo.py | dev | 执行 git rm 标记删除(dev 上已删除此文件) |
| T7 | 解决冲突 — fof_demo_20.py | dev | 执行 git checkout --theirs 选择 dev 版本 |
| T8 | commit 到 dev | dev | commit 2fa9bf4 |
| T9 | checkout master | master | 回到 master |
| T10 | merge dev | master | 产生冲突 |
| T11 | 解决冲突 — fof_demo_20.py | master | 执行 git checkout --theirs 选择 dev 版本 |
| T12 | commit merge | master | commit 6676501 |
| T13 | push master | master | 推送到远程 |
2.2 关键错误
错误 1:stash pop 时 git rm 删除了 etf_demo.py
stash 中有 etf_demo.py,但 dev 分支上该文件已被删除。stash pop 产生冲突后,执行 git rm 将其标记为删除。这个删除被 commit 到了 dev 分支。
错误 2:merge master 时 --theirs 覆盖了 master 的改动
merge dev → master 时,--theirs 选择了 dev 的版本。dev 分支上 manager_factory.py 没有 00401_etf 配置(因为 dev 是从 master 检出后,stash 恢复时没有包含 manager_factory.py 的修改),所以 master 上的改动被覆盖了。
根本原因:merge 时使用 --theirs 等同于"接受对方版本,丢弃自己版本",当对方版本不包含某些改动时,这些改动就丢失了。
三、恢复过程
3.1 定位丢失代码
git log --all --oneline -- portfolio/algo/manager_factory.py
# 找到 commit 0cc6e24 包含 00401_etf 配置
git show 0cc6e24:portfolio/algo/manager_factory.py
# 查看该 commit 的完整文件内容
3.2 恢复代码
从 commit 0cc6e24 提取 manager_factory.py 的完整内容,手动合并到当前文件:
- 添加
_weight_RP5配置 - 更新风筹引擎参数(
_en_MT0210C05R20f、_en_MTteste等) - 更新管理人配置(
_m_e0401_test等) - 添加 00401_etf 注册
3.3 提交恢复
git add -A
git commit -m "feat: restore manager 00401_etf and update manager factory config"
git push origin dev
# commit: ece4655
四、教训与改进
4.1 合并冲突处理原则
- 永远不要盲目使用
--theirs或--ours - 每次 merge 前,先
git diff HEAD...MERGE_HEAD对比两边的差异 - 对于涉及核心配置/注册表的文件,必须逐文件检查冲突
4.2 stash 操作注意事项
- stash pop 产生冲突时,不要急于
git rm或git checkout - 先确认冲突文件在目标分支上的状态(是否真的应该删除)
- 如果不确定,先用
git stash show查看 stash 内容
4.3 代码恢复技巧
git show <commit>:<file>— 查看任意 commit 的文件内容git log --all --oneline -- <file>— 追踪文件变更历史git reflog— 找回被覆盖的 commit- 关键改动后及时 push,减少本地丢失风险
4.4 流程改进
- merge 前先在本地
git merge --no-commit预览冲突 - 涉及注册表/配置文件的改动,review 时重点检查
- 重要分支(master)的 merge 操作,建议先创建临时分支验证
五、验证
# 验证 00401_etf 已恢复
git show HEAD:portfolio/algo/manager_factory.py | grep -n "0401"
# 应输出注册相关行
# 验证文件完整性
git diff 0cc6e24 -- portfolio/algo/manager_factory.py
# 应无差异(或仅有预期差异)
六、相关笔记
- H2Hx8uG1yJoV — 组合算法:200个etf标的日志分析(含本次修复记录)