和往常同样,每一个人团队开发者都在本身的本地分支上进行平常工做,相互独立又相互联系,一直以来相安无事,但是某天下午,上级领导忽然急冲冲的打电话告诉你线上出bug
了,须要你紧急修复,下班以前必须解决!html
咱们天生就是创造 bug
的特殊群体,天天都在和各类各样的 bug
打交道,早已经习惯了这样的工做节奏,再也没有当初刚刚遇到紧急问题的手足无措,先喝杯茶,冷静一下,而后汇报领导说:放心吧!保证30min
内解决问题!git
学习了分支操做的相关知识,团队内部就基本的开发流程达成一致:github
假设线上是主干 master
分支,开发是 dev
分支,团队成员是自定义 custom
分支,平时开发时在你们在各自 custom
分支上工做,完成分配任务后再合并到开发 dev
分支,等到开发分支功能稳定后,由项目领导负责合并到主干分支 master
.vim
上述流程只是开发流程的简化版,实际状况更加复杂,后续再介绍
gitflow
工做流相关知识.app
因为是线上出现 bug
,理所固然是基于 master
分支检出临时分支,修复分支代号为 issue-110
,而后定位 bug
并提交,最后再合并到 master
分支,如此一来成功修复 bug
,完成既定任务,问心无愧准备下班回家!学习
若是真的向上述步骤那样操做,显然还不够冷静,刚才那一杯茶算是白喝了!由于这样操做可能会丢失现场数据,那不少工做岂不是白作了,下面简单演示一下:编码
(一). 事发前正在自定义的 snow
分支上愉快编码中...code
# 线上分支 `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
.htm
(2.1) 基于 master
分支检出 issue-110
分支,并修复提交.blog
# 注意: 事发时正在思考人生,此时更改还没有添加到暂存区! $ 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}