← 上一章:【冷知識】標籤跟分支有什麼不一樣? 下一章:【狀況題】不小心把帳號密碼放在 Git 裡了,想把它刪掉… →
【狀況題】手邊的工作做到一半,臨時要切換到別的任務
在公司工作或多或少有經歷過這樣的情境:
你手邊的工作做到一半…
老闆:「那個誰誰誰,網站掛了,你趕快先來修一下這個功能…」
先不管心情好不好,既然老闆都開口了,為了生活只好暫時先乖乖聽話,先把手邊的進度放旁邊…
那就先 Commit 目前的進度吧!
簡單的做法,也是我常會做的做法,就是先不管那麼多,先把目前所有的修改先存下來。假設這是目前的狀況,而且我正在 cat
分支進行功能開發:
$ git add --all
$ git commit -m "not finish yet"
[cat 9bf1f43] not finish yet
2 files changed, 1 insertion(+)
create mode 100644 cat3.html
然後就可以切到有問題的分支先進行功能修復,待完成之後再切回原來做一半的 cat
分支,然後再 Reset 一下,把剛剛做一半的東西拆回來繼續做:
$ git reset HEAD^
然後就可以接著繼續做了。
使用 Stash
遇到這個情況,剛剛那個先 Commit,之後再 Reset 回來的做法是一種做法,另一種做法是使用 Git 的 Stash 功能。先看一下目前的狀態:
$ git status
On branch cat
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: cat1.html
modified: cat2.html
modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
目前的狀態正在修改 cat1.html
、cat2.html
以及 index.html
這幾個檔案。因為老闆急著召喚要去做別的事,這時候可使用 git stash
指令,把這些修改先「存」起來:
$ git stash
Saved working directory and index state WIP on cat: b174a5a add cat 2
注意!
Untracked 狀態的檔案預設沒辦法被 Stash,需要額外使用
-u
參數。
看一下目前的狀態:
$ git status
On branch cat
nothing to commit, working tree clean
好像跟剛 Commit 完一樣的乾淨了。
剛剛那些檔案存到哪去了?讓我們看一下:
$ git stash list
stash@{0}: WIP on cat: b174a5a add cat 2
看起來目前只有一份狀態被存起來,最前面的 stash@{0}
是這個 Stash 的代名詞,而後面的 WIP
字樣是「Work In Progress」,就是工作進行中的意思。Stash 可以放很多份,例如我再放一份到 Stash:
$ git stash list
stash@{0}: WIP on dog: 053fb21 add dog 2
stash@{1}: WIP on cat: b174a5a add cat 2
剛剛原來 stash@{0}
的現在變成 stash@{1}
了。
使用 SourceTree 也可以做這件事,在上方選單有一顆「Stash」按鈕,按下之後便會出現對話框
填寫後按下 OK 即可完成。在左邊側邊欄可以看到一個「STASHES」選單,裡面會放著目前所有的 Stash 的內容:
把 Stash 撿回來用
好啦,剛剛的修復任務完成了,可以繼續把剛剛存起來的東西再拿出來了。再次看一下目前的 Stash 列表:
$ git stash list
stash@{0}: On dog: not finish yet!
stash@{1}: WIP on dog: 053fb21 add dog 2
stash@{2}: WIP on cat: b174a5a add cat 2
這個 stash@{2}
應該是我剛剛最一開始做一半的進度,所以我要把它撿回來做:
$ git stash pop stash@{2}
On branch cat
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: cat1.html
modified: cat2.html
modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{2} (80091001b2022e0fb3f8c7ee6cffcefa207d00be)
說明如下:
- 使用
pop
指令,可以把某個 Stash 拿出來並套用在目前的分支上。套用成功之後,那個套用過的 Stash 就會被刪除。 - 如果後面沒有指定要 pop 哪一個 Stash,會從編號最小的,也就是
stash@{0}
開始拿(也就是最後疊上去的那次)。
如果那個 Stash 確定不要,可以使用 drop
指令:
$ git stash drop stash@{0}
Dropped stash@{0} (87390c02bbfc8cf7a38fb42f6f3a357e51ce6cd1)
這樣就可以把那個 Stash 從列表裡刪掉了。
要把 Stash 撿回來用,除了 pop
之外,另一個指令是 apply
:
$ git stash apply stash@{0}
這是指會把 stash@{0}
這個 Stash 拿來套用在現在的分支上,但 Stash 不會刪除,還是會留在 Stash 列表上。所以你可把 pop
指令看成「apply
Stash + drop
Stash」。
使用 SourceTree 要套用 Stash 的話,就是在指定的 Stash 上按滑鼠右鍵,然後選擇「Apply Stash」功能即可:
所以,使用哪一種比較好?
其實都可,看每個人的習慣,還有對 Git 的熟悉程度會有不同的答案。如果你問我,我會跟你說我比較喜歡第一種,就是先 Commit 之後再 Reset 回來繼續做,對我個人而言,我覺得這樣相對比使用 Stash 來得直覺一些。
Comments