git 入門教程之緊急修復

和往常同樣,每一個人團隊開發者都在本身的本地分支上進行平常工做,相互獨立又相互聯繫,一直以來相安無事,但是某天下午,上級領導忽然急衝衝的打電話告訴你線上出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"

git-branch-snow.png

(二). 事發時直接檢出主分 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
$

git-branch-issue-110.png

(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
$

git-branch-fixbug-master.png

(三). 事發後切換回自定義 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
$

git-branch-fixbug-snow.png

如今還打算下班嗎?你所作的更改由於沒有提交或者不能提交形成所有丟失!

結果

由於手頭工做進行到一半沒法提交或者忘記提交等緣由,爲了臨時修復緊急 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}
相關文章
相關標籤/搜索