my-gitbook
Blog
  • 👨‍💻简介
  • 入门教程
    • markdown 入门教程
    • git 入门教程
      • 初识 git
        • 安装 git
        • 配置 git
      • 实战 git
        • 本地仓库
        • 版本管理
        • 回到过去
        • 基本概念
        • 版本控制
        • 撤销更改
        • 删除文件
        • 远程仓库
        • 分支管理
          • 分支总览
          • 冲突合并
          • 分支策略
          • 紧急修复
          • 变基合并
          • 协同开发
          • 本地和远程仓库的本质
        • 里程碑式标签
      • 私人定制
        • 忽略文件
        • 同步推送多Git仓库
      • 搭建私服
      • 扩展工具
        • git bash 常见命令
        • git bash 朋友圈
        • git bash 扩展tree命令
        • git bash 扩展命令(上)
        • git bash 扩展命令(中)
        • git bash 扩展命令(下)
        • git submodule 父子模块
      • 沙海拾贝
        • 知识速查
        • 备忘录[译]
    • github 入门教程
      • github 访问速度太慢
      • github 徽章从何而来
    • gitbook 入门教程
      • 准备阶段
        • 前置知识
        • 环境要求
      • 快速体验
        • gitbook-cli 命令行操作
        • gitbook-editor 编辑器操作
        • gitbook.com 官网操作
      • 高级进阶
        • 插件介绍
          • 实用插件
          • 主题插件
          • 开发插件
        • 导出电子书
        • 发布电子书
      • 公众号引流
      • 优化搜索
      • 常见问题
        • 热加载失败治标之法
        • 初始化默认折叠效果
      • 参考更多
  • 编程笔记
    • java 学习笔记
    • go 学习笔记
    • php 学习笔记
    • python 学习笔记
      • 入门教程
        • 00-ubuntu安装
        • 01-Linux基础
        • 操作系统的发展史(科普章节)
      • Django教程
        • Django 学习笔记
    • Linux 学习笔记
      • Linux基础
      • Linux全栈运维
  • 兴趣开发
    • 从零开始搭建服务器
      • 从登录服务器开始
      • 更加优雅地部署项目
      • 跟着官方体验 Docker
      • 快速尝鲜基于 Docker 部署项目
      • 利用阿里云 OSS部署静态网站
      • 免费实现https访问网站
      • webhook
    • 运维部署
      • docker 环境
      • docker 操作
      • docker compose
      • docker + nginx
      • docker + blog
      • docker + resume
      • docker + gitbook
      • docker + Bark
      • docker + py12306
      • docker + mojo-Weixin
      • docker + wechat-work-message-push-go
      • docker + email
      • docker + mysql
      • docker + springboot
      • docker + redis
      • docker + gogs
      • docker + gitlab
      • docker + gitea
      • docker + crawlab
    • 工具资源
      • 给 mac 装个 vmware 虚拟机
        • 给 mac 虚拟机装个 windows
        • 给 mac 虚拟机装个 centos
        • 给 mac 虚拟机装个 ubuntu
      • 给 windows 装个 vmware 虚拟机
        • 给 windows 虚拟机装个 mac
        • 给 windows 虚拟机装个 windows
        • 给 windows 虚拟机装个 centos
        • 给 windows 虚拟机装个 ubuntu
      • 公众号历史文章备份
        • Ryen
        • 苏生不惑
        • Python技术
      • 学会开发专属 chrome 插件
      • 攻克 12306 前端加密算法
    • 如何写作
      • markdown 和富文本
      • markdown 转富文本
      • csv 半手动数据统计
      • js 半手动数据统计
      • 简述优选文章统计
      • 快速上手Mermaid流程图
      • 常见问题
  • 读书观感
    • 大数据浪潮之巅:新技术商业制胜之道
  • 程序人生
    • 待完成清单
      • yarn快速入门
      • gulp快速入门
      • nvm快速入门
      • lodash快速入门
      • regexper快速入门
      • sublime快速入门
      • github 快速入门
      • svn 快速入门
      • java 快速入门
      • mysql 快速入门
      • maven 快速入门
      • tomcat 快速入门
      • gitignore 快速入门
      • android studio 快速入门
      • npm 快速入门
      • nginx 快速入门
    • 其他
      • 重装开发环境
      • 钉钉签到提醒
      • 倒计时提醒
      • 关注网站
      • 转型之路
      • 历史统计
      • 关于作者
      • 捐赠支持
由 GitBook 提供支持
在本页
  • 背景
  • 错误示例
  • 正确示例
  • 小结

这有帮助吗?

在GitHub上编辑
  1. 入门教程
  2. git 入门教程
  3. 实战 git
  4. 分支管理

紧急修复

和往常一样,每个人团队开发者都在自己的本地分支上进行日常工作,相互独立又相互联系,一直以来相安无事,可是某天下午,上级领导突然急冲冲的打电话告诉你线上出bug了,需要你紧急修复,下班之前必须解决!

我们天生就是创造 bug 的特殊群体,每天都在和各种各样的 bug 打交道,早已经习惯了这样的工作节奏,再也没有当初刚刚遇到紧急问题的手足无措,先喝杯茶,冷静一下,然后汇报领导说:放心吧!保证30min 内解决问题!

背景

学习了分支操作的相关知识,团队内部就基本的开发流程达成一致:

假设线上是主干 master 分支,开发是 dev 分支,团队成员是自定义 custom 分支,平时开发时在大家在各自 custom 分支上工作,完成分配任务后再合并到开发 dev 分支,等到开发分支功能稳定后,由项目领导负责合并到主干分支 master .

上述流程只是开发流程的简化版,实际情况更加复杂,后续再介绍 gitflow 工作流相关知识.

由于是线上出现 bug,理所当然是基于 master 分支检出临时分支,修复分支代号为 issue-110,然后定位 bug 并提交,最后再合并到 master 分支,如此一来成功修复 bug,完成既定任务,心安理得准备下班回家!

如果真的向上述步骤那样操作,显然还不够冷静,刚才那一杯茶算是白喝了!因为这样操作可能会丢失现场数据,那很多工作岂不是白做了,下面简单演示一下:

错误示例

(一). 事发前正在自定义的 snow 分支上愉快编码中...

# 线上分支 `master`,开发分支 `dev`,自定义分支 `snow`,当前正处于自定义分支
$ git branch
  dev
  master
* snow
# 接到领导电话前正在自定义 `snow` 分支上进行愉快编码中...
$ echo "Happy coding" >> test.txt
$ git add test.txt
$ git commit -m  "Happy coding"

(二). 事发时直接检出主分 master 分支,并紧急修复 bug .

(2.1) 基于 master 分支检出 issue-110 分支,并修复提交.

# 注意: 事发时正在思考人生,此时更改尚未添加到暂存区!
$ echo "who am i" >> test.txt

# 当前情况下,默认不允许直接切换到其他分支,因为工作区更改会被重写,这里为了演示错误示例,强制切换!
$ git checkout -f master 

# 基于主干 `master` 分支检出修复 `issue-110`分支
$ git checkout -b issue-110
Switched to a new branch 'issue-110'

# 定位线上 `bug`并修复,假设将 `fast forward` 更改为 `fast forward not recommend`,瞬间修复 `bug`有没有!
$ cat test.txt
add test.txt
see https://gitbook.prlrr.com/git/usage/remote-repository.html
learn git branch
see https://gitbook.prlrr.com/git/usage/branch-overview.html
git commit c1
git commit c2 and c3
git checkout -b dev
fast forward
$ vim test.txt
$ cat test.txt
add test.txt
see https://gitbook.prlrr.com/git/usage/remote-repository.html
learn git branch
see https://gitbook.prlrr.com/git/usage/branch-overview.html
git commit c1
git commit c2 and c3
git checkout -b dev
fast forward not recommend

# 修复 `bug` 后,提交更改并备注已修复
$ git add test.txt
$ git commit -m "fix bug about issue-110"
[issue-110 e60c8ad] fix bug about issue-110
 1 file changed, 1 insertion(+), 1 deletion(-)
sunpodeMacBook-Pro:git-demo sunpo$ git status
On branch issue-110
nothing to commit, working tree clean
$ 

(2.1) 切换到主干 master 分支,并合并修复 issue-110 分支

# 切换回 `master` 分支,合并修复 `issue-110` 分支
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ git merge issue-110
Updating 3fe94c0..e60c8ad
Fast-forward
 test.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

# 验证 `bug` 已修复: 更改为 `fast forward not recommend`
$ cat test.txt
add test.txt
see https://gitbook.prlrr.com/git/usage/remote-repository.html
learn git branch
see https://gitbook.prlrr.com/git/usage/branch-overview.html
git commit c1
git commit c2 and c3
git checkout -b dev
fast forward not recommend
$ 

(三). 事发后切换回自定义 snow 分支,打算下班回家.

# 切换回 `snow` 分支,发现丢失了事发前的未保存更改:`who am i`
$ git checkout snow
Switched to branch 'snow'
$ cat test.txt
add test.txt
see https://gitbook.prlrr.com/git/usage/remote-repository.html
learn git branch
see https://gitbook.prlrr.com/git/usage/branch-overview.html
git commit c1
git commit c2 and c3
git checkout -b dev
fast forward
Happy coding
$ 

现在还打算下班吗?你所做的更改因为没有提交或者不能提交造成全部丢失!

结果

因为手头工作进行到一半无法提交或者忘记提交等原因,为了临时修复紧急 bug 而直接切换到目标分支再回来时发现更改全部丢失,相当于那部分工作白忙活了!

正确示例

经过上述错误示例的惨痛教训后,再也不敢轻易切换分支了,原因在于工作区更改并没有被提交,或者说不能提交,如果能够有一种机制来保护案发现场,这样我们就能放心切换到其他分支工作,回来时一切如初,那该多好?

幸运的是,git 确实提供这么一种机制,git stash 命令临时存储工作区,类似"草稿箱"作用.

(一). 恢复工作区丢失更改,并使用 git stash 命令保存现场.

# 修复工作区丢失更改: 同样未添加到暂存区
$ echo "learn git stash" >> test.txt
$ cat test.txt
add test.txt
see https://gitbook.prlrr.com/git/usage/remote-repository.html
learn git branch
see https://gitbook.prlrr.com/git/usage/branch-overview.html
git commit c1
git commit c2 and c3
git checkout -b dev
fast forward
Happy coding
learn git stash

# 保护现场: 存储到"草稿箱"
$ git stash
Saved working directory and index state WIP on snow: 93227ba Happy coding

(二). 切换到开发 dev 分支并合并修复 issue-110 分支.

# 切换到开发 `dev` 分支
$ git checkout dev
Switched to branch 'dev'
sunpodeMacBook-Pro:git-demo sunpo$ git status
On branch dev
nothing to commit, working tree clean
# 合并修复 `issue-110` 分支
$ git merge issue-110
Updating 3fe94c0..e60c8ad
Fast-forward
 test.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sunpodeMacBook-Pro:git-demo sunpo$ git status
On branch dev
nothing to commit, working tree clean
$ 

(三). 切换回自定义 snow 分支,并恢复工作现场.

# 切换回自定义 `snow` 分支
$ git checkout snow
Switched to branch 'snow'
sunpodeMacBook-Pro:git-demo sunpo$ git status
On branch snow
nothing to commit, working tree clean
$ 

git status 命令返回结果怎么显示工作区是干净的,好不容易才将丢失的更改找回来怎么又不见了?!逗我玩?

冷静,冷静,不要慌,既然工作现场已经保存到"草稿箱",那我们想要找回总要去"草稿箱"才能取出来吧?现在让我们看一下"草稿箱"有没有我们的工作现场?

# 查看存储的"草稿箱"列表
$ git stash list
stash@{0}: WIP on snow: 93227ba Happy coding
$ 

这里的 stash@{0} 是草稿 id,因为"草稿箱"允许保存多条草稿!

现在放心了吧,保存的"草稿"安然无恙躺在未知的某个地方,现在我们想办法恢复回工作区即可!

  • git stash apply 恢复草稿,然后 git stash drop 删除草稿

  • git stash pop 恢复并删除草稿

# 恢复工作现场
$ git stash pop
On branch snow
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (b0c8ddc034d21f31204c82e9838fc5d4c01a49a8)

# 工作现场已恢复,更改未添加到暂存区,`learn git stash` 又恢复了!
$ git status
On branch snow
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ cat test.txt
add test.txt
see https://gitbook.prlrr.com/git/usage/remote-repository.html
learn git branch
see https://gitbook.prlrr.com/git/usage/branch-overview.html
git commit c1
git commit c2 and c3
git checkout -b dev
fast forward
Happy coding
learn git stash

结果

不论手头工作有没有提交,一旦工作区保存到"草稿箱"后,就放心大胆切换分支进行工作,回来时岁月静好,一切如初!

小结

紧急修复 bug 时,可以通过 git stash 保护工作现场,然后再切换到目标分支,检出修复分支,完成修复后切换到目标分支,合并修复分支,最后删除修复分支,此时再切换回本地分支后一切如初!

  • 工作区更改添加到"草稿箱" : git stash,支持多次添加到"草稿箱"

  • 列出"草稿箱"内容 : git stash list

  • 恢复"草稿箱"内容 : git stash apply

  • 删除"草稿箱"内容 : git stash drop

  • 恢复并删除"草稿箱"内容 : git stash pop

  • 恢复|删除指定"草稿箱"内容 : git stash <stash-id>,例如 git stash apply stash@{0}

上一页分支策略下一页变基合并

最后更新于1年前

这有帮助吗?

git-branch-snow.png
git-branch-issue-110.png
git-branch-fixbug-master.png
git-branch-fixbug-snow.png