大家好,今天的文章我們來介紹git當中一個非常常用的功能——儲藏。
大家在協同開發的時候應該都有這樣的經歷,有的時候我們的功能開發了一半,因為某些原因我們想要checkout到其他的分支上檢視程式碼或者是執行某個工作。但是如果我們直接執行checkout,git會禁止我們的行為。
我拿本地的專案舉個例子,可以看到當我們執行了checkout命令之後,git提示我們在一些檔案的改動會被覆蓋,所以拒絕了我們的checkout命令。
這個時候應該怎麼辦呢?最好的辦法當然是使用git commit把改動提交了。但問題是有的時候我們不想提交一些程式碼,比如還沒有經過嚴謹的測試,或者是我們臨時開發的一些測試功能等等。在這種情況下commit也是不合適的,即使提交了了,之後在push之前也會要把commit撤銷了。但如果一不小心忘記了,可能就會造成悲劇。
針對這個問題,git提供了一個解決策略就是stash功能。
儲藏改動
git stash可以將本地還沒有提交的改動全部儲存起來。接著,我們在之前的某一篇文章當中加上一行-test stash。
我們執行一下git diff,可以看到這行改動。
接著我們執行git stash,會發現我們的git目錄又回到了沒有改動的狀態。再執行git diff也看不到任何改動了。
這是因為git把我們本地還沒有提交的改動都暫存了起來,這樣方便我們進行checkout或者是其他一些操作,而不會起衝突或者是其他的影響。
應用改動
那麼當我們操作完成之後,想要還原剛才暫存起來的內容,這個時候應該怎麼辦呢?
也有辦法,我們只需要使用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記錄,非常方便,不過我個人沒有用過,因為實際工作當中沒有遇到這麼複雜的情況。
今天的文章就到這裡,衷心祝願大家每天都有所收穫。如果還喜歡今天的內容的話,請來一個三連支援吧~(點贊、關注、轉發)