Git Stash用法

大搜車-自娛發表於2015-08-04

最近在使用Git管理專案工程的時候,遇到了很多問題,也學習到了很多關於Git常見使用的技巧,下面就其中關於Git Stash的用法和大家分享下。
首先,簡單介紹下Git Stash命令的用法,詳細的用法在man文件中有相關介紹,下面我來說明常見的使用。
git stash: 備份當前的工作區的內容,從最近的一次提交中讀取相關內容,讓工作區保證和上次提交的內容一致。同時,將當前的工作區內容儲存到Git棧中。
git stash pop: 從Git棧中讀取最近一次儲存的內容,恢復工作區的相關內容。由於可能存在多個Stash的內容,所以用棧來管理,pop會從最近的一個stash中讀取內容並恢復。
git stash list: 顯示Git棧內的所有備份,可以利用這個列表來決定從那個地方恢復。
git stash clear: 清空Git棧。此時使用gitg等圖形化工具會發現,原來stash的哪些節點都消失了。
關於Git Stash的詳細解釋,適用場合,這裡做一個說明:

使用git的時候,我們往往使用branch解決任務切換問題,例如,我們往往會建一個自己的分支去修改和除錯程式碼, 如果別人或者自己發現原有的分支上有個不得不修改的bug,我們往往會把完成一半的程式碼 commit提交到本地倉庫,然後切換分支去修改bug,改好之後再切換回來。這樣的話往往log上會有大量不必要的記錄。其實如果我們不想提交完成一半或者不完善的程式碼,但是卻不得不去修改一個緊急Bug,那麼使用'git stash'就可以將你當前未提交到本地(和伺服器)的程式碼推入到Git的棧中,這時候你的工作區間和上一次提交的內容是完全一樣的,所以你可以放心的修 Bug,等到修完Bug,提交到伺服器上後,再使用'git stash apply'將以前一半的工作應用回來。也許有的人會說,那我可不可以多次將未提交的程式碼壓入到棧中?答案是可以的。當你多次使用'git stash'命令後,你的棧裡將充滿了未提交的程式碼,這時候你會對將哪個版本應用回來有些困惑,'git stash list'命令可以將當前的Git棧資訊列印出來,你只需要將找到對應的版本號,例如使用'git stash apply stash@{1}'就可以將你指定版本號為stash@{1}的工作取出來,當你將所有的棧都應用回來的時候,可以使用'git stash clear'來將棧清空。
在這裡順便提下git format
-patch -n , n是具體某個數字, 例如 'git format-patch -1' 這時便會根據log生成一個對應的補丁,如果 'git format-patch -2' 那麼便會生成2個補丁,當然前提是你的log上有至少有兩個記錄。


看過上面的資訊,就可以知道使用場合了:當前工作區內容已被修改,但是並未完成。這時Boss來了,說前面的分支上面有一個Bug,需要立即修復。可是我又不想提交目前的修改,因為修改沒有完成。但是,不提交的話,又沒有辦法checkout到前面的分支。此時用Git Stash就相當於備份工作區了。然後在Checkout過去修改,就能夠達到儲存當前工作區,並及時恢復的作用。

下面,將我使用過程中遇到的一個問題和大家分享:

首先,在Git Stash之後,提交圖如下所示:

從圖中可以看到,develop和newdevelop是在同一個分支上,因為分支newdevelop是在develop分支的基礎上開發的。想加入一個新的特性,所以就開了newdevelop分支,然後就在上面加東西,加特性,該程式碼。這個時候工作的內容已經變化了,但是develop和newdevelop都是指向同一個提交的,因為newdevelop上面還木有提交。
這個時候,Boss來了,說develop上面有個Bug,趕快改一下,手頭的工作先放放,穩定版本不能有缺陷。沒辦法,當前正在newdevelop上搞的high呢,就Git Stash一下。所以會看到上面有兩個節點,紅色以及上面一個。就是stash之後的結果,注意是在newdevelop上面進行的stash。

正如前面所說,stash會暫存當前的工作區內容,然後將工作區內容保持和上次提交相同,此時內容都是上面8a32那個提交的內容。從終端中檢視相應的資訊內容,如下:

印證了簽名的說法,newdevelop是有修改,modified,然後stash之後,工作區是最近一次提交,此時newdevelop和develop都是相同的,所以再git status檢視發現,都一樣,nothing to commit.

然後Stash完成之後,就要Fix Bug了。為此,回到develop分支上進行修復,然後提交,完成後的提交圖如下所示:

從途中可以看到,newdevelop還是在下面,因為指向的是老的那個8a32的commit。新的develop由於修復了Bug,所以產生一個新提交。


然後在develop上面修復了Bug之後,在回到newdevelop上面進行一個新的特性的繼續編碼,此時checkout回去的時候,沒有神馬內容可以提交,因為都存在Stash中了,沒有任何修改。如上圖。

那麼,恢復工作區內容吧。於是git stash pop(注意這裡由於只Stash了一次所以使用pop,具體你存放了多少,要恢復哪一個要自己清楚,否則會出錯!)

恢復之後,從上圖中可以看到,此時再git status就會發現檔案有修改,說明恢復過來了。然後就繼續編碼,提交一個穩定的新特性版本,如下圖,產生的新提交為0906.
然後再檢視提交圖,會發現,stash pop之後,對應的存放的stash被清空掉了,提交圖中,newdevelop上面對應一個新的提交。並且在develop上面。分支的develop那個紅色,即為前面修復Bug的那個提交。


總結起來:
操作很簡單,但是頭腦要清楚。要在哪個分支上修復Bug,要暫存哪個地方的內容,之後修復完了在那個地方提交,然後要到哪個分支上面恢復工作區,都是需要注意的,否則,很容易造成提交圖混亂。只有弄清楚了工作流程,才不容易出錯,才能保證很高的工作效率。
最後一句:Git是神器,就要看你如何駕馭它了。

相關文章