前言
有時候我們會遇到需臨時修改它分支的狀況,這邊的臨時代表正在開發的項目並不是它分支的內容,比如說 master 分支需做緊急修改,但我們目前正在跑 feature 分支的進度,這時你可能會將 feature 尚未提交成 commit 的修改內容複製到一個空白文件上,以確保修改內容不會不見,最後當 master 分支修改完成時,再將修改內容貼回到 feature 上,這確實也是個辦法,但其實不用這麼麻煩,Git 本身就有專門處理此情況的指令,名為 stash,可將當下分支的修改內容暫存起來,日後有需要再將它取出即可。
筆記重點
- stash 暫存修改內容
- reset 模擬暫存修改內容
- Git 指令回顧
stash 暫存修改內容
讓我們先新增一個專案並提交兩次 commit 紀錄:
1 | mkdir project |
建立 feature
分支並提交數次 commit 紀錄
1 | git checkout -b feature |
假設 feature
分支第一階段的需求已經達到了:
1 | git checkout master |
此時的線路圖狀態為:
feature
分支已被合併到 master
分支,接著進行第二階段的工作:
1 | git checkout feature |
此時的檔案狀態為:
假設老闆臨時叫你去修改 master
分支的內容,我們可使用以下指令將當前分支的修改給暫存下來:
- 暫存當前分支修改內容:
1 | git stash |
- 暫存當前分支修改內容 (包含未追蹤):
1 | git stash -u |
因為 db.json
屬於未追蹤的檔案,所以在這邊需要添加 -u
參數告知需包含未追蹤檔案,在這邊補充一點,你可能看過下面這道類似的命令:
1 | git stash save |
這道命令在 v2.16 的 Git 版本已被棄用,取而代之的是使用 push
命令:
1 | git stash push |
事實上,這兩道命令都可以達到相同的目的,只差在 save
無法擁有 push
的 pathspec 參數功能,由於較冷門,這邊我們不討論 pathspec 參數,你可能會好奇,那 git stash push
的功能是什麼?簡單來講,git stash
就等效於 git stash push
,少打 push
只是方便你輸入而已,但我建議還是輸入完整指令比較好,等等會在說明,此時的檔案狀態為:
你會發現修改內容都不見了,如同使用 git checkout .
與 git clean -f
一般,事實上,它是把修改內容都暫存到了 /.git/refs/stash
檔案內,我們可使用以下指令查看所有暫存內容:
1 | git stash list |
暫存以清單呈現:
為什麼會是以清單呈現呢?暫存檔總不可能只有一個吧,這邊我們到 master
分支也新增一個暫存檔看看:
1 | git checkout master |
這邊有一個大雷點,-m
參數是用來告知 Git 使用自訂的暫存訊息,必須使用完整的 git stash push
才能作用,你沒辦法寫做 git stash -m
,這樣會跳找不到命令,這是我實測的結果,所以為什麼前面說盡量寫成完整的命令,就是這個原因,此時的暫存內容就會多一筆:
目前我們已經把修改內容暫存到 Git 內了,假設你已經完成臨時的任務,此時可使用以下指令取出暫存內容:
- 將最新暫存套用至當前分支,成功後銷毀暫存 (即 stash@{0}):
1 | git stash pop |
- 將指定暫存套用至當前分支,成功後銷毀暫存:
1 | git stash pop stash@{1} |
以下為 feature
分支取出暫存內容的結果:
此時你當時所做的修改就都回來了,是不是很方便?使用 pop
可以把某個 stash 拿出來並套用在目前的分支上,套用完成即銷毀這個暫存內容,如果你不想銷毀暫存內容,可改用以下指令:
- 將最新暫存套用至當前分支,成功後保留暫存:
1 | git stash apply |
- 將指定暫存套用至當前分支,成功後保留暫存:
1 | git stash apply stash@{1} |
apply
只會將暫存做套用的動作,並不會銷毀暫存,如果你不想要某個暫存了,可使用以下指令:
- 刪除最新暫存 (即 stash@{0}):
1 | git stash drop |
- 刪除指定暫存:
1 | git stash drop stash@{1} |
- 刪除全部暫存:
1 | git stash clear |
以上就是 stash 命令的相關操作。
reset 模擬暫存修改內容
這邊主要參考 為你自己學 Git 文章,使用 reset 來模擬暫存修改內容,讓我們先看目前的狀態:
由於剛剛我們只有套用 feature
分支的暫存檔,這邊我們也連同套用 master
分支的暫存檔。
其實關於暫存的操作並不一定要使用 stash 來完成,我們也可以透過土法煉鋼的方式來操作,直接將修改內容提交至本地庫:
1 | git add . |
此時的 Git 就會是 nothing to commit 狀態,與使用 git stash
結果相同,假設我們完成它分支的任務了,使用以下指令把 commit 還原到工作目錄:
1 | git reset HEAD^ --mixed |
--mixed
為 reset 預設模式,即丟回工作目錄,這邊千萬不要使用 --hard
模式阿,你的修改內容就要說掰掰了 (還是可以用 reflog 查詢並還原拉)。
此時的結果就會與使用 git stash pop
相同,並沒有說哪一種方式比較好,只要你夠熟悉 Git 指令,確實有相當多的方法可以達到同樣效果。
Git 指令回顧
1 | # 暫存當前分支修改內容 |