git 入门教程之紧急修复
和往常一样,每个人团队开发者都在自己的本地分支上进行日常工作,相互独立又相互联系,一直以来相安无事,可是某天下午,上级领导突然急冲冲的打电话告诉你线上出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://snowdreams1006.github.io/git/usage/remote-repository.html
learn git branch
see https://snowdreams1006.github.io/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://snowdreams1006.github.io/git/usage/remote-repository.html
learn git branch
see https://snowdreams1006.github.io/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://snowdreams1006.github.io/git/usage/remote-repository.html
learn git branch
see https://snowdreams1006.github.io/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://snowdreams1006.github.io/git/usage/remote-repository.html
learn git branch
see https://snowdreams1006.github.io/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://snowdreams1006.github.io/git/usage/remote-repository.html
learn git branch
see https://snowdreams1006.github.io/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://snowdreams1006.github.io/git/usage/remote-repository.html
learn git branch
see https://snowdreams1006.github.io/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}
git 入门教程之紧急修复的更多相关文章
- git 入门教程
git 入门教程之协同开发 前面我们已经介绍过远程仓库的相关概念,不过那时并没有深入探讨,只是讲解了如何创建远程仓库以及推送最新工作成果到远程仓库,实际上远程仓库对于团队协同开发很重要,不仅仅是团队协 ...
- 廖雪峰Git入门教程
廖雪峰Git入门教程 2018-05-24 23:05:11 0 0 0 https://www.liaoxuefeng.com/wiki/00137395163059296 ...
- git 入门教程之版本控制
版本控制 我们知道 git 是分布式版本控制系统,所以称被控制对象是版本本身没错,但是从git 命令中发现,并没有版本这个名词,有的只是commit,所以前几节我一直称其为提交. 为了避免后续教程引发 ...
- Git入门教程
参考文献: 1. Pro Git 2. Git教程 3. Git教程 4. 图解Git
- git 入门教程之备忘录[译]
备忘录[译] 创建 | Create 克隆一个已存在的仓库 | Clone an existing repository git clone git@github.com:snowdreams1006 ...
- git 入门教程之变基合并
git 鼓励大量使用分支---"早建分支!多用分支!",这是因为即便创建再多的分支也不会造成存储或内存开销,并且分支的作用有助于我们分解逻辑工作,这样一样其实比维护单一臃肿分支要简 ...
- git 入门教程之分支策略
默认情况下合并分支常常直接使用 git merge 命令,是最方便快速的合并方法.其实这种情况下 git 采用的是 fast forward 模式,特点是删除分支后,会丢失分支信息,好像从来没存在该分 ...
- git 入门教程之远程仓库
远程仓库 如果说本地仓库已经足够个人进行版本控制了,那么远程仓库则使多人合作开发成为可能. 如果你只是打算自己使用git,你的工作内容不需要发布给其他人看,那就用不到远程仓库的概念. git 是分布式 ...
- git 入门教程之撤销更改
撤销更改 相信你已经了解了 git 的基本概念,也清楚了工作区,暂存区和版本库的关系,现在让我们用所学的知识继解决实际问题吧! 背景 正常看得见的目录是我们最为熟悉的工作区,在工作中不可能总是100% ...
随机推荐
- python搭建web服务
import json from urlparse import parse_qs from wsgiref.simple_server import make_server import os im ...
- NetStandard;.netCore;FX(.netFrameWork)之间引用关系
.NetStandard;.netCore;FX(.NetFrameWork)之间引用关系 FX引用.NetCore:不通过 NetStandard引用.NetCore:不通过 .NetCor ...
- (转)Python__slots__详解
原文:https://www.cnblogs.com/rainfd/p/slots.html#top 摘要 当一个类需要创建大量实例时,可以通过__slots__声明实例所需要的属性, 例如,clas ...
- Ocelot简易教程(一)之Ocelot是什么
作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9557375.html Ocelot简易教程目录 Ocelot简易教程(一)之Ocelot是什么 Ocel ...
- sql server 备份与恢复系列五 完整模式下的备份与还原
一.概述 前面介绍了简单恢复模式和大容量恢复模式,这篇继续写完整恢复模式下的备份与还原.在完整恢复模式里最大的优点是只要能成功备份尾日志,就可以还原到日志备份内包含的任何时点("时点恢复&q ...
- 我可能不懂Array.prototype.sort
今天 fix 我们后台系统的一些 bug.系统是基于 beego 和模板开发的,各种前后端代码揉作一团,没有格式,没有 eslint,全局变量满天飞,连 js 代码都有后端的插值,读起来非常 酸爽. ...
- Android--UI之Radio、Check、Toggle
前言 这篇博客讲解一下Android平台下,RadioButton.CheckBox以及ToggleButton三个控件的用法,因为这三个控件之中都存在一个选中或是没选中的状态,所以放在一起讲解. 这 ...
- 进程间通信IPC-消息队列
前言: 消息队列就是一个消息的链表.可以把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程可以向其中按照一定的规则添加新消息:对消息队列有读权限的进程则可以从消息队列中读走消 ...
- selenium3环境搭建以及各浏览器驱动的使用方法
想了解更多关于seleniu请访问selenium官网 https://www.seleniumhq.org/ 以Selenium3.0.2版本为例介绍在Python中如何安装及使用,具体操作步骤如下 ...
- 使用LayoutInflater添加一个布局引用
LayoutInflater 与 xml 的<include/>的区别,至今没搞清楚,下面记录一下LayoutInflater引用一个布局并立即显示呈现的方法: private void ...