網頁

2019/11/2

Git stash 暫存正在修改的內容

當在Git專案的某條分支修改了部分檔案且工作尚未完成,而臨時因為工作需要(各種理由急件,插單,bug修復等)切換到另一個分支,而必須先把目前分支進行到一半的修改暫存起來時,可使用git stash指令將目前做的暫時存起,等待回從另一條分支切回後再取出。

例如目前git專案在master分支有一支檔案叫hello.txt內容如下。

hello.txt

原本的內容

然後做點修改,加入一點文字如下

hello.txt

原本的內容
正在修改的內容...

使用git status檢視可以看到hello.txt因為修改了一點內容仍在unstaged狀態。。

$ git status
On branch master
Your branch is up to date with 'origin/master'.

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:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")

現在因為臨時需要必須切到另一條dev分支工作,而必須將master分支正在修改的內容暫存起來,此時就可以用git stash把剛在master全部正在修改的unstaged的內容暫存起來。

$ git stash
Saved working directory and index state WIP on master: 84e1d3a origin content

如果只要stash某支特定檔案,使用git stash push <file><file>為要stash的檔案路徑及名稱。

$ git stash hello.txt
Saved working directory and index state WIP on master: 84e1d3a origin content

stash的訊息顯示「儲存工作目錄並索引master分支的84e1d3a的內容」。


stash有點類似分支,不過這分支只是暫存用的。使用git log --all --graph --decorate來檢視記錄,可以看到多了refs/stash,此即為stash產生的暫存分支。

$ git log --all --graph --decorate
*   commit 414a9df81ba280a7de50be634c789f4d83f679de (refs/stash)
|\  Merge: 84e1d3a b11776f
| | Author: matt 
| | Date:   Sat Nov 2 15:49:05 2019 +0800
| |
| |     WIP on master: 84e1d3a origin content
| |
| * commit b11776f9b40bbc52c95ca05d0c1b5d88ef313f8d
|/  Author: matt 
|   Date:   Sat Nov 2 15:49:05 2019 +0800
|
|       index on master: 84e1d3a origin content
|
* commit 84e1d3a83ff507fa1f615ce7564b00c56654fd6d (HEAD -> master, origin/master)
| Author: matt 
| Date:   Sat Nov 2 15:38:37 2019 +0800
|
|     origin content
|

stash後再使用git status會發現原本unstaged狀態的hello.txt不見了,打開hello.txt也可以看到裡面的內容變成加入正在修改的內容前的狀態。

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

此時可以使用git stash list指令檢視被stash的清單。

$ git stash list
stash@{0}: WIP on master: 84e1d3a origin content

上面的stash@{0}就是剛剛的stash。


把正在修改的內容stash起來後就可以放心地切換到其他分支工作了。

使用git stash show -p可顯示最後一筆stash與目前工作目錄中內容的差異。

$ git stash show -p
diff --git a/hello.txt b/hello.txt
index 24b1dd1..b29acaf 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1,2 @@
-原本的內容
\ No newline at end of file
+原本的內容
+正在修改的內容...
\ No newline at end of file

在其他分支工作完後切回原本的master分支,使用git stash pop指令可取回剛剛被stash的狀態。

$ git stash pop
On branch master
Your branch is up to date with 'origin/master'.

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:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (414a9df81ba280a7de50be634c789f4d83f679de)

此時可以看到剛剛被stash的正在修改的內容又回來了,hello.txt又回到unstaged狀態,內容也回復成正在修改的內容狀態,如此就可以繼續完成剩下的工作了。


此時再用git stash list又看不到任何stash了。


在上面取出stash時是使用git stash pop指令取出儲藏,這樣stash中的儲藏會被自動清除。

若希望取出stash時不要清除儲藏,可改用git stash apply指令。

$ git stash apply
On branch master
Your branch is up to date with 'origin/master'.

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:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")

接著用git stash list可以看到儲藏的內容仍然存在。

$ git stash list
stash@{0}: WIP on master: 84e1d3a origin content

若想清除stash中的儲藏,可使用git stash drop清除最近一筆stash儲藏。

$ git stash drop
Dropped refs/stash@{0} (2da87bc9086d3cb07a1b664f57d11e34e61e924b)

若要移除某一筆stash儲藏,使用git stash drop <stash><stash>為stash的名稱。

git stash drop stash@{0}
Dropped stash@{0} (b4d4999fa30cdf4b026b5e7a51c860380e206aab)

或使用git stash clear清除全部的stash儲藏。

git stash clear

stash儲藏被刪除後,使用git log --all --graph --decorate檢視狀態如下,可以看到stash暫時用的分支refs/stash消失了。

$ git log --all --graph --decorate
* commit 84e1d3a83ff507fa1f615ce7564b00c56654fd6d (HEAD -> master, origin/master)
| Author: matt 
| Date:   Sat Nov 2 15:38:37 2019 +0800
|
|     origin content
|


參考:

1 則留言: