你們好,今天的文章咱們來介紹git當中一個很是經常使用的功能——儲藏。git
你們在協同開發的時候應該都有這樣的經歷,有的時候咱們的功能開發了一半,由於某些緣由咱們想要checkout到其餘的分支上查看代碼或者是執行某個工做。可是若是咱們直接執行checkout,git會禁止咱們的行爲。web
我拿本地的項目舉個例子,能夠看到當咱們執行了checkout命令以後,git提示咱們在一些文件的改動會被覆蓋,因此拒絕了咱們的checkout命令。app
這個時候應該怎麼辦呢?最好的辦法固然是使用git commit把改動提交了。但問題是有的時候咱們不想提交一些代碼,好比尚未通過嚴謹的測試,或者是咱們臨時開發的一些測試功能等等。在這種狀況下commit也是不合適的,即便提交了了,以後在push以前也會要把commit撤銷了。但若是一不當心忘記了,可能就會形成悲劇。編輯器
針對這個問題,git提供了一個解決策略就是stash功能。測試
git stash能夠將本地尚未提交的改動所有存儲起來。接着,咱們在以前的某一篇文章當中加上一行-test stash。flex
咱們執行一下git diff,能夠看到這行改動。url
接着咱們執行git stash,會發現咱們的git目錄又回到了沒有改動的狀態。再執行git diff也看不到任何改動了。spa
這是由於git把咱們本地尚未提交的改動都暫存了起來,這樣方便咱們進行checkout或者是其餘一些操做,而不會起衝突或者是其餘的影響。3d
那麼當咱們操做完成以後,想要還原剛纔暫存起來的內容,這個時候應該怎麼辦呢?code
也有辦法,咱們只須要使用git stash apply或者是git stash pop這兩個命令就能夠將剛纔暫存起來的內容還原了。可是這裏有一個問題,就是stash apply和pop之間是不一樣的。
這裏涉及到stash內部的實現機制,stash內部實際上是經過堆棧實現的。pop對於堆棧而言很明確,就是彈出的意思。也就是說若是咱們使用的是pop,那麼當咱們pop以後,這條記錄會在堆棧當中刪除。而若是使用的是apply呢,記錄不會從堆棧當中刪除,仍然會保留下來。
通常狀況下我使用pop多一些,可是pop也有缺點,好比pop沒有辦法選擇應用的記錄。咱們可使用git stash list來查看一下當前堆棧當中已經有的記錄。
若是咱們使用git stash pop的話,默認的是應用的棧頂的記錄,也就是stash@{0}。但若是咱們使用stash apply的話,咱們能夠自由選擇咱們想要應用的記錄。好比若是咱們想要應用最後一條記錄的話,咱們能夠這樣:
git stash apply stash@{2}
關於應用儲存的修改也有一些細節,首先是儲藏和修改對應的分支能夠不一樣。咱們能夠在一個分支儲藏,以後切換到另一個分支進行應用。而且若是咱們在應用以前修改了一樣的內容的話,也會引發合併衝突。
另外就是當咱們應用儲藏的時候,會發現咱們以前add過的文件又從新回到了未暫存的狀態。若是咱們想要從新回到文件被暫存的狀態時,咱們可使用index選項來執行。
git stash apply --index
對於咱們已經不想要的儲藏記錄,咱們能夠執行git stash drop來進行刪除。
除了上述的功能以外,git stash還有一些其餘的用法。
好比--keep-index選項,在不加這個選項的時候,當咱們使用git stash,它會把全部沒有commit的內容所有stash。可是有的時候咱們不但願這樣,咱們但願它只暫存咱們沒有add到暫存區的內容。這個時候咱們就能夠經過這個參數實現。
另一個參數是-u或者是--include-untracked,咱們從這個名字上也看得出來。它們的意思是在stash的時候將新建立而且尚未被git管理的文件也一併儲藏起來。
除此以外,還有--patch的功能也很經常使用。patch咱們曾經在上篇文章講解交互式命令的時候講到過,它能夠將git針對的改動縮小到代碼而不是文件級別。交互式地和咱們操做哪些代碼層面的改動須要存儲起來,操做方法和上篇文章介紹的同樣。你們若是有所遺忘能夠在文末找到上一篇的文章進行回顧。
最後一個功能是從儲藏上新建一個分支,有的時候咱們先儲存了代碼以後又繼續進行了一些工做。這個時候若是咱們再恢復從前的改動則會引發衝突。這個時候咱們能夠運行git stash branch新建一個新的分支,在這個分支上應用咱們的提交。
git stash branch applystash
應用成功以後Git會自動拋棄掉對應的stash記錄,很是方便,不過我我的沒有用過,由於實際工做當中沒有遇到這麼複雜的狀況。
今天的文章就到這裏,衷心祝願你們天天都有所收穫。若是還喜歡今天的內容的話,請來一個三連支持吧~(點贊、關注、轉發)