我在當前分支開發(fā)了,開發(fā)一部分,然后需要在其他分支解決問題,怎么辦?
在介紹合并的時候,有提到需要保持分支干凈,所以將修改的內(nèi)容提交后再合并操作。此時如果還不想提交的話,可以使用 git stash 命令將修改的內(nèi)容保存至 堆棧區(qū),待合適的時候恢復。如果在錯誤的分支進行了開發(fā),也可以先將內(nèi)容保存至堆棧區(qū),然后在目標分支恢復內(nèi)容。
stash 顧名思義就是儲藏,在 Git 管理中可以將工作區(qū)的內(nèi)容先存起來,然后合適的時候再拿出來。
學會使用 stash 能很好的輔助我們進行分支的管理和維護,命令也比較簡單,主要有以下幾個操作。
儲存修改的內(nèi)容
git stash
可以將所有未提交的修改(工作區(qū)和暫存區(qū)的內(nèi)容,不包括 untracked 文件或目錄) 保存至堆棧區(qū),在需要的時候恢復內(nèi)容,可以是同分支,也可以是不同的分支。
在 master 分支創(chuàng)建一個名為 stash 1.txt 的文件,然后使用 stash 放入堆棧區(qū)

git stash save <message>
- 用法同
git stash,如果使用git stash,會產(chǎn)生一條名為" WIP on branchname …?"的內(nèi)容,使用git stash save可以添加描述信息
創(chuàng)建一個 stash 2.txt,再操作一次,那么 stash 2 這個改動也被放入了堆棧區(qū)

默認情況下,git stash 會緩存下列文件:
- 添加到暫存區(qū)的修改(staged changes)
- Git 跟蹤的但并未添加到暫存區(qū)的修改(unstaged changes)
但不會緩存以下文件:
- 在工作目錄中新的文件(untracked files)
- 被忽略的文件(ignored files)
git stash 命令提供了參數(shù)用于緩存上面兩種類型的文件。
- 使用
-u或者--include-untracked可以 stash untracked 文件。 - 使用
-a或者--all命令可以 stash 當前目錄下的所有修改。
完整的 git stash 命令如下,可以根據(jù)需求使用(參考文檔 https://git-scm.com/docs/git-stash/2.0.0)
git stash [save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all] [<message>]]
順便說下,在參數(shù)說明中,中括號[] 的內(nèi)容表示是可選項
查看 stash 棧
git stash list 可以查看 stash 的內(nèi)容
下面顯示的兩條,分別是第一次操作 git stash 和第二次操作 git stash save stash 2 產(chǎn)生的兩條記錄,可以看出,stash 儲藏是棧的形式,最新的一條記錄在棧頂。

應用 stash
如果想應用 stash 的內(nèi)容,有兩種命令可以實現(xiàn)
git stash pop
git stash pop 命令會恢復之前緩存的工作目錄,這個指令將緩存堆棧中的第一個 stash 刪除(棧是先進后出)

在 pop 之后 我們最后入棧的改動 stash 2.txt 恢復了,而且 stash 列表也被刪除了
pop 后面也可以添加 <stash>, git stash pop <stash> 來恢復指定的 stash 內(nèi)容
<stash> 表示 stash 名稱,具體用 stash@{n} 表示。比如stash@{0}是棧頂(最新的)的內(nèi)容, stash@{1} 就是更早的,前一個內(nèi)容。通過 git stash list 也可以查看每個的 stash 編號
git stash apply
后面也可接 <stash> ,git stash apply <stash> 應用某一個stash 內(nèi)容,不刪除記錄,默認是應用棧頂(即最新)的一條 stash
為了方便說明,再新建一個 stash 3.txt ,并且 stash

此時將前一個 stash 1.txt 恢復: git stash apply stash@{1}

文件 stash 1.txt 恢復了,并且在stash list 中也沒有被刪除
(可能有人問,前面恢復的 文件 stash 2.txt 去哪兒了?在進行 stash 3 操作時,stash 2.txt 和 stash 3.txt 都是在暫存區(qū),所以都暫存到第三次 stash 中了)
刪除 stash 內(nèi)容
若某個 stash 內(nèi)容不會再被應用了,可以使用 git stash drop [<stash>] 刪除,默認為棧頂?shù)?stash
刪除掉剛剛恢復的內(nèi)容 git stash drop stash@{1}

清空 stash 堆棧
git stash clear會將堆棧所有內(nèi)容清空
使用 git stash clear 之后,再看下 list, list 中已經(jīng)沒有內(nèi)容了

查看 stash 的 diff
git stash show [ -p | --patch] <stash>, show 這個命令會顯示 stash 的修改內(nèi)容
當前 添加一個名為 stash.txt 文件,并且在 text.txt 文件追加一行內(nèi)容 "Line: stash add",將這些修改 stash 一下
-
git stash show可以查看 stash 的 diff -
git stash show -p添加-p或者--patch可以查看 stash 的全部 diff -
git stash show [ -p | --patch] [<stash>]show 后面可以跟 <stash> 查看特定 stash 的 diff
創(chuàng)建含有 stash 內(nèi)容的分支
其實在應用 stash 的過程中,也可能和當前內(nèi)容產(chǎn)生沖突,比如下面 ===== 上面是應用 stash 之前的內(nèi)容,下面就是 stash 的內(nèi)容,此時也是需要解決沖突的(和合并差不多)
<<<<<<< Updated upstream
Line:stash branch
=======
Line: stash add
>>>>>>> Stashed changes
如果 stash 的內(nèi)容是未完成的內(nèi)容,此時應用還要先處理沖突再繼續(xù)完成之前的內(nèi)容,那么推薦使用 stash 的 branch 命令
git stash branch <new_branch> [<stash>]
這個命令的作用是:會創(chuàng)建一個新的分支,檢出(checkout)在儲藏工作時的所處的提交,重新應用 stash 內(nèi)容,如果成功,將會丟棄(drop)該條 stash 的內(nèi)容。
什么意思呢,看下圖:現(xiàn)在在 Commit 2 除,儲存了一次修改的內(nèi)容,然后提交了 C3,之后又 stash 了一次
如果是 git stash branch <new_branch> stash@{1}那么就是在 C2 處 創(chuàng)建并切換一個分支,并將 Stash 1 的內(nèi)容帶到新的分支中,此時 Stash 1 就會在 list 中刪除

上面介紹了 stash 用法,stash 功能在 Git 版本管理中是非常實用的功能,再來復習下 stash 相關(guān)命令
git stash 儲存修改的內(nèi)容
git stash save [<message>] 儲存修改的內(nèi)容,可以添加描述,如果沒有描述 Git 會默認添加,
git stash save -u [<message>] 前面可以儲存的內(nèi)容包含暫存區(qū)和工作區(qū)的內(nèi)容
- 使用
-u或者--include-untracked可以 stash untracked 文件。 - 使用
-a或者--all命令可以 stash 當前目錄下的所有修改。
git stash list 查看已經(jīng) stash 的棧
git stash show 可以查看 stash 的 diff
git stash show -p 添加 -p 或者 --patch 可以查看 stash 的全部 diff
上面命令后面都可以添加 <stash> 以查看特定 stash 的 diff
git stash pop <stash> 應用指定的 stash 內(nèi)容,并刪除 list 中的 stash 記錄
git stash apply <stash> 應用指定的 stash 內(nèi)容,不刪除 list 中的 stash 記錄
git stash drop <stash> 刪除指定的 stash 內(nèi)容
git stash clear 清空 stash 棧
git stash branch <new_branch> [<stash>] 在儲藏工作時的所處的提交處創(chuàng)建一個新分支并切換,重新應用 stash 內(nèi)容,完成后,將會丟棄該條 stash 的內(nèi)容。
以上未明確 <stash> 時 ,默認為棧頂?shù)?stash
stash 的命令有些多,但其實并不復雜,孰能生巧,會在 Git 管理中起到大的作用的!
系列文章傳送門
Git 入門系列(一)- Git 概念/安裝/基本操作/遠程推送更新
Git 入門系列(二)- 修改管理 / 撤銷操作 / 命令及區(qū)間關(guān)系
Git 入門系列(三)- 分支(上)創(chuàng)建與切換 / 合并 / 查看 / 刪除
Git 入門系列(四)- 分支(下)合并解決沖突 / 遠程分支
Git 入門系列(五)- stash 貯藏
Git 入門系列(六)- 標簽 tag
Git 入門系列(七)- 可視化 Git 管理工具
Git 入門系列(八) - FAQ
歡迎關(guān)注個人公眾號,【程序媛春哥的手記】

