之前在介紹分支時有提過,因為可能有多個任務或臨時任務在進行中,
因此可以自由的切換分支來完成工作,但工作到一半的分支如果不存到暫存區就必須跟其他分支共用工作目錄的成果,
甚至修改到互相衝突的檔案,那就連分支都沒辦法切換過去了。
可是如果存到暫存區或乾脆提交又覺得不適當,因為工作還沒完成,commit 該怎麼寫呀?
其實像這樣實際的狀況,我們應該是有個變通方案,將目前的成果存下來提交是沒錯,
但臨時跑去完成別的工作後回來應該把剛剛的成果接回來繼續完成會比較好,這樣就兩全其美囉。
reset
最簡單的方式就是使用 reset 切版。
現在我們在 new_test 分支編輯了某個檔案到一半,但臨時被老闆叫去修系統的 bug 那就先把目前的成果存下來。
$ git add .
$ git commit -m '做到一半'
[new_test 4d51034] 做到一半
1 file changed, 2 insertions(+)
然後切換到修 bug 的分支進行工作,工作完成後切回來 new_test 分支,
使用 reset 把剛剛的工作拆回來繼續做:
$ git reset HEAD~
Unstaged changes after reset:
M abc.txt
# 拆回來了,看一下狀態
$ git status
On branch new_test
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: abc.txt
no changes added to commit (use "git add" and/or "git commit -a")
沒錯, abc.txt 呈現剛剛編輯的狀態且還沒從工作目錄存到暫存區,那就是我們剛剛的工作狀態了,
這時候就可以繼續原本的工作囉。
stash
除了 reset 還有另外一個方式,那就是 stash 指令。
剛剛拆回來的狀況假設又被抓去做別的分支了,那就使用 stash 先把這裡的工作存起來:
$ git stash
Saved working directory and index state WIP on new_test: 0ceca24 增加一個 word
檔
還沒被追蹤的檔案 Untracked 要使用參數 -u
才會被 stash 記錄喔。
$ git status
On branch new_test
nothing to commit, working tree clean
很有趣,看起來的狀態就跟剛提交完一樣。
那剛剛做到一半的成果存去哪了?
$ git stash list
stash@{0}: WIP on new_test: 0ceca24 增加一個 word 檔
stash@{0}
是目前被暫存下來的工作代號,WIP
是工作進行中字樣,
所以同時可以有很多筆暫存工作,代號就是 stash 0 1 2 等。
號碼數字越少表示越新,所以 0 是最新。
那臨時工作完成了要怎麼把 stash 抓回來繼續做呢?
答案是使用 pop
把暫存紀錄接回來做:
$ git stash pop stash@{0}
On branch new_test
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: abc.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{0} (54320c87cabef3ec7bd118c1861bff34aed1cdcc)
有看到 Dropped
這個字吧,這表示 stash 接回來後該紀錄會從 stash 中消失,
如果 pop
後面不接號碼的話就預設 0 也就是最新的暫存紀錄。
除了使用 pop 也可以使用 apply (其他參數語法一樣) 把暫存資料接回來,
差別是 apply 接回來後該暫存紀錄還留在 stash 當中,可以使用 drop
參數刪掉他。
因此,有人說 pop 是 apply + drop
以上兩種方式,你喜歡哪一種呢?