git stash用法詳解

admin發表於2018-07-31

假設這樣一個情形,正在開發一個專案,距離完成還有一段距離。

這時有一個更為緊要的問題處理,需要切換到其他分支。

為了不丟失正在開發的程式碼,可以將未完成的程式碼提交,但也因此增加一個多餘提交。

使用git stash命令可以更好的解決類似問題。

一.將改動儲藏起來:

使用如下命令可以儲存當前的修改,將工作和暫存區的狀態儲存起來以備將來使用,並將當前工作區和暫存區重置為最近一次提交後的狀態("乾淨"狀態的工作區,暫存區會根據命令引數的不同決定是否重置。)

[Shell] 純文字檢視 複製程式碼
$ git stash

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/012347w1k8g412g1gs1dd8.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

git stash是git stash push的縮寫形式(git stash save不推薦使用),此命令有不少常用引數,後面介紹。

兩個命令的區別可以參閱git statsh svae與git statsh push區別一章節。

當然也可以給暫存新增說明,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git stash -m "螞蟻部落stash測試"

(1).將未跟蹤檔案儲藏:

預設狀態,git stash命令只能將已經跟蹤和非.gitignore忽略的檔案儲藏,未跟蹤的檔案不會被儲存。

首先看下當前專案狀態,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git status

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/012459r7y1vdkiewikxwve.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

修改了readme.txt檔案,softwhy.txt檔案未跟蹤,執行git stash push命令效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/012519b6w9dk6jdrwvp69r.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

由此可見,工作區被修改的檔案被暫存起來,但是未跟蹤檔案不被儲存。

使用如下命令可以將未跟蹤檔案一併儲存:

[Shell] 純文字檢視 複製程式碼
$ git stash push -u

-u是--include-untracked的簡略形式。

現在檢視專案狀態:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/012558bvv4lzc6lrllldl8.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

由上圖可見,被修改的檔案連同未跟蹤檔案也被儲存起來了。

(2).儲存.gitignore忽略的檔案:

關於.gitignore用法可以參閱.gitignore忽略跟蹤指定檔案一章節。

.gitignore規定antzone.txt檔案忽略跟蹤,專案目錄截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/012700ti9k5x7xd97ucdth.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

執行如下程式碼:

[Shell] 純文字檢視 複製程式碼
$ git stash push -a

-a是--all的簡寫形式,規定被修改的檔案連同被忽略檔案也被儲存起來,現在檢視專案目錄:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/012820ji8coichf9hk0a8b.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

由上圖可見,被忽略的antzone.txt已經被儲存起來。

(3).是否重置暫存區:

在預設狀態,git stash命令會將工作區和暫存區內容重置為最近一次提交後的內容。

首先看一下當前專案狀態,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git status

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/012903rhr5x5lxq26nikr5.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

狀態解釋如下:

(1).readme.txt檔案被修改,並且提交到暫存區。

(2).readme.txt的修改再被提交到暫存區以後,再一次被修改。

(3).還有兩個未跟蹤的檔案(antzone.txt和softwhy.txt)。

下面我們暫存一下,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git stash push -k

-k是--keep-index簡略形式,表示不重置暫存區,預設值是--no-keep-index。

現在再來看一下專案狀態,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git status

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/013050mnjs3nk3jvxwggkk.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

狀態解釋如下:

(1).工作區被重置為最近一次commit提交後的狀態。

(2).由於使用-k,暫存區的狀態被儲存,不會被重置為最近一次commit提交後的狀態。

(3).還有兩個未跟蹤的檔案(antzone.txt和softwhy.txt)。

二.檢視所有儲存內容:

可以多次儲存內容,然後形成一個列表,可以使用如下程式碼檢視:

[Shell] 純文字檢視 複製程式碼
$ git stash list

程式碼效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/013136wpzfjr5xxjx2oxg9.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

最新的儲藏在最上面。

三.應用儲藏內容:

再次應用儲藏起來的內容最為常見的兩個命令是:

(1).git stash appy

(2).git stash pop

程式碼例項如下:

[Shell] 純文字檢視 複製程式碼
$ git stash apply

應用最新的儲藏內容,也就是用最新儲藏的內容重置工作區或者暫存區。

如果有多個儲藏,也可以指定應用哪個儲藏,程式碼例項如下:

[Shell] 純文字檢視 複製程式碼
$ git stash apply stash@{1}

git stash pop功能與git stash appy大致一樣,區別如下:

(1).pop正如它的名字,將儲藏內容彈出並應用,儲藏內容會被從儲藏列表中刪除。

(2).appy僅僅是應用,不會將儲藏從儲藏列表中刪除。

是否重置暫存區:

和上面在儲存的時候,是否重置暫存區類似,在應用儲存的時候,也可以指定是否重置暫存區。

對readme.txt檔案修改,並將修改提交到暫存區,狀態截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/013301vmtmzmt9mv9nqkmq.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

現在將當前狀態儲存起來,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git stash

預設會將工作區和暫存區的改動都儲藏起來,下面應用儲藏內容:

[Shell] 純文字檢視 複製程式碼
$ git stash pop

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/31/013356vzt1jj1jj8f3i93y.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以看到,readme.txt檔案處於修改狀態,說明上述命令並沒有把儲藏應用到暫存區,也就是沒重置。

[Shell] 純文字檢視 複製程式碼
$ git stash pop --index

新增--index即可實現重置暫存區功能。

git stash apply使用方式與git stash pop相同,不再重複。

四.刪除儲存內容:

刪除操作比較簡單,下面給出簡單示例:

[Shell] 純文字檢視 複製程式碼
$ git stash drop stash@{1} # 刪除指定儲藏
$  git stash clear #  刪除所有儲藏

五.在指定儲藏基礎上建立分支:

本文不多介紹,具體參閱Git基於指定stash儲藏建立分支一章節。