记一次严重的 Git 分支提交错误与修复复盘

记一次严重的 Git 分支提交错误与修复复盘

1. 问题背景:错把 develop 的代码合入了 main

事故性质: 严重分支污染事故。

事故描述 : 在项目开发过程中,一系列(共10个)本应提交到 develop 开发分支的功能,被错误地直接提交并推送到了受保护的 main 主分支。由于 main 分支是生产环境的直接代码源,且其提交历史已被共享,这次事故对代码库的稳定性和版本历史的清晰度构成了严重威胁。

受影响的提交范围:

  • 8ec3e9c (refactor(test): 统一MinIO测试配置为环境变量驱动)
  • 173fb2b (refactor(api): 统一视频上传并修复服务初始化)

2. 核心挑战:如何在不"炸毁"仓库的前提下修复?

主要挑战在于,这些错误的提交已经被推送到了远程共享分支 (origin/main)。在这种情况下,严禁使用 git reset --hardgit rebase 等会重写历史的命令。因为这会强制改变已共享的提交历史,导致团队其他成员的本地仓库与远程仓库产生严重冲突和不一致,引发更大的混乱。

因此,我们必须采用一种既能修正错误,又不破坏现有提交历史的安全策略。

3. 解决方案:"撤销"与"移植"

我们采用了"撤销并移植" (Revert and Cherry-pick) 的两阶段策略,这是处理此类问题的行业标准最佳实践。

  1. 阶段一:修复 main 分支

    • 目标 : 将 main 分支的内容恢复到事故发生前的状态。
    • 工具 : git revert
    • 原理 : git revert 会创建一个新的提交 ,这个新提交的内容与目标提交的内容正好相反,从而"撤销"目标提交的更改。它不删除历史,而是在历史之上追加一次修复,是修改共享分支的安全方式。
  2. 阶段二:更新 develop 分支

    • 目标 : 将被撤销的10个提交正确地应用到 develop 分支。
    • 工具 : git cherry-pick
    • 原理 : git cherry-pick 可以选择一个或多个现有的提交,并像"复制-粘贴"一样,将它们的更改在当前分支上重新应用一遍,创建出内容相同但哈希值不同的新提交。

4. 详细修复流程

阶段一:在 main 分支上执行 revert

此阶段的目标是安全地"撤销"main 分支上的10个错误提交。

flowchart TD subgraph "阶段一:修复 Main 分支" A[开始] --> B{识别出 main 分支上
10个错误提交}; B --> C[执行 git revert --no-commit
准备批量撤销]; C --> D[执行 git commit
将所有撤销合并为
一个修复提交]; D --> E[执行 git push origin main
将修复推送到远程]; E --> F[结束: main 分支内容恢复]; end

具体执行的命令:

  1. 定位 revert 的范围:

    bash 复制代码
    # 找到系列提交的起点 (8ec3e9c) 的上一个提交
    git rev-parse 8ec3e9c~1
    # 输出: 59944d65b252f6603c856b861bdb2e02320e37ce
  2. 执行 revert 操作:

    bash 复制代码
    # 撤销从 59944d6 (不含) 到 173fb2b (含) 的所有提交
    # --no-commit 标志让我们可以将所有 revert 合并为一次提交
    git revert --no-commit 59944d6..173fb2b
  3. 创建清晰的修复提交:

    bash 复制代码
    git commit -m "revert: Revert 10 commits to move to develop branch"
  4. 同步到远程:

    bash 复制代码
    git push origin main

阶段二:在 develop 分支上执行 cherry-pick

此阶段的目标是将那10个功能提交正确地"移植"到 develop 分支。

flowchart TD subgraph "阶段二:更新 Develop 分支" A[开始] --> B[切换到 develop 分支]; B --> C[执行 git cherry-pick
将10个提交
应用到 develop 分支]; C --> D[执行 git push origin develop
将新提交推送到远程]; D --> E[结束: develop 分支更新完毕]; end

具体执行的命令:

  1. 切换分支:

    bash 复制代码
    git checkout develop
  2. 执行 cherry-pick 操作:

    bash 复制代码
    # 将 59944d6 (不含) 到 173fb2b (含) 的提交应用到当前分支
    git cherry-pick 59944d6..173fb2b
  3. 同步到远程:

    bash 复制代码
    git push origin develop

5. 经验总结

本次事故通过标准的 git revertgit cherry-pick 流程得到了安全、彻底的解决。

  • main 分支: 代码内容已恢复到事故前的状态,同时保留了清晰、不可篡改的提交历史,记录了从事故发生到修复的全过程。
  • develop 分支: 成功接收了所有本应属于它的功能提交,开发工作可以正常继续。
  • 团队协作: 由于未使用任何重写历史的危险命令,本次修复对团队其他成员完全透明,不会造成任何协作冲突。

这次事故提醒我们,在执行 git commitgit push 操作前,务必通过 git statusgit branch 确认当前所在分支,避免类似问题再次发生。

相关推荐
shiwulou17 分钟前
PbRL | 近两年论文阅读的不完全总结
后端
yuniko-n15 分钟前
【MySQL】通俗易懂的 MVCC 与事务
数据库·后端·sql·mysql
今天过得怎么样22 分钟前
彻底搞懂 Spring Boot 中 properties 和 YAML 的区别
后端
qq_124987075325 分钟前
基于springboot的幼儿园家校联动小程序的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·spring·微信小程序·小程序
m0_7263658344 分钟前
大力学习台灯T6/T6Pro 救砖实战:macOS/Windows 用 mtkclient 从 Fastboot 无限重启完整恢复(含固件下载地址)
python·github·智能硬件
武子康1 小时前
大数据-189 Nginx JSON 日志接入 ELK:ZK+Kafka+Elasticsearch 7.3.0+Kibana 实战搭建
大数据·后端·elasticsearch
断春风1 小时前
订单超时自动取消系统架构解析
后端·系统架构
Angletank2 小时前
SpringBoot中ORM组件通过JAP组件的使用
spring boot·后端·orm·jpa
moxiaoran57532 小时前
Go语言的map
开发语言·后端·golang
小信啊啊2 小时前
Go语言数组
开发语言·后端·golang