1、什麼是Git存儲
有時當你在項目的一個分支上,已經工作一段時間後,所有東西都進入了混亂的狀態, 而這時你想要切換到另一個分支做一點別的事情。 問題是,你不想僅僅因爲這點別的事,而把剛剛做了一半的工作進行一次提交。
針對這個問題,可以使用 git stash
命令來解決。(stash:貯藏)
git stash
命令會處理工作目錄的髒狀態,即:根據文件的修改與暫存的改動,然後將未完成的修改保存到一個棧上, 而你可以在任何時候重新應用這些改動(甚至在不同的分支上)。
2、Git存儲的常用命令
-
git stash
、git stash push
、git stash save
:保存當前工作進度,會把暫存區和工作區的改動stash(保存)起來。執行完這個命令後,在運行git status
命令,就會發現當前工作目錄中有一個乾淨的工作區,沒有任何改動。使用
git stash save '註釋'
可以給存儲的進度添加註釋。 git stash list
:顯示Git存儲棧中的進度列表。-
git stash pop [–index] [stash_id]
:Git存儲棧會把工作區和暫存區的改動都恢復到工作區,通過git stash pop
命令恢復進度後,同時會刪除Git存儲棧中當前進度的存儲。1)
git stash pop
命令:如果不指定,Git會把最近一次的Git存儲恢復到工作區。2)
git stash pop --index
命令:恢復最新的Git存儲到工作區和暫存區,嘗試將原來暫存區的改動,恢復到暫存區。3)
git stash pop [stash_id]
命令:恢復指定的進度到工作區。stash_id是通過git stash list
命令得到的。例如:stash@{1}
。 git stash apply [–index] [stash_id]
:不刪除恢復的Git存儲,其餘和git stash pop
命令一樣。git stash drop [stash_id]
:刪除一個存儲的進度。如果不指定stash_id,則默認刪除最新的存儲進度。git stash clear
:刪除所有存儲的進度。git stash show
:顯示stash的內容具體是什麼,使用方法如git stash show stash@{0}
。git stash branch <branchname> <stash>
:基於進度創建分支。
說明:
當我們執行
git stash apply
之後,發現所有的文件都變成了未暫存的,如果想維持原來的樣子,也就是暫存過的依舊是暫存狀態,那麼可以使用git stash apply --index
命令。即:
--index
選項作用,除了恢復工作區的文件外,還嘗試恢復暫存區。
拓展:截至 2017 年 10 月下旬,Git 郵件列表上進行了廣泛討論,該討論中棄用了
git stash save
命令, 代之以現有的git stash push
命令。主因是git stash push
引入了貯藏選定的 路徑規範 的選項, 而有些東西git stash save
不支持。
git stash save
不會很快就消失,所以不用擔心它突然不見。
3、常用參數說明
-
-k
:即--keep-index
參數:在保存進度後,不會將暫存區重置。默認會將暫存區和工作區強制重置。
--patch
:會顯示工作區和HEAD的差異。通過對差異文件的編輯,決定在進度中,最終要保存的,工作區的內容。通過編輯差異文件,可以在進度中排除無關內容。-
-u
:即--include-untracked
參數:默認情況下,
git stash
只會存儲已修改和暫存的 已跟蹤 文件。 如果指定--include-untracked
或-u
選項,Git 也會存儲任何未跟蹤文件。然而在Git存儲中,包含未跟蹤的文件中,仍然不會包含明確 忽略 的文件。 要額外包含忽略的文件,請使用
--all
或-a
選項。
4、Git存儲演示
現在本地版本庫中情況如下:
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git log --oneline
4f69dbb (HEAD -> dev) 第3次提交,在dev分支新增stash.txt文件
89e03bd (master) 第2次提交,readme.txt文件,v2版本
80add2e 第1次提交,新增readme.txt文件
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git reflog
4f69dbb (HEAD -> dev) HEAD@{1}: commit: 第3次提交,在dev分支新增stash.txt文件
89e03bd (master) HEAD@{2}: checkout: moving from master to dev
89e03bd (master) HEAD@{3}: commit: 第2次提交,readme.txt文件,v2版本
80add2e HEAD@{4}: commit (initial): 第1次提交,新增readme.txt文件
有兩分支,master
分支和dev
分支。
此時正在開發dev
分支中的stash.txt
文件。
下面開始演示 git stash
命令用法。
1)從未完成工作dev
分支,切換到master
工作。
# 1.開發dev分支中的stash.txt文件。
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ echo "stash.txt v2" >> stash.txt
# 2.查看工作目錄中文件狀態
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git status
On branch dev
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: stash.txt
no changes added to commit (use "git add" and/or "git commit -a")
# 3.切換到master分支處理事情
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
stash.txt
Please commit your changes or stash them before you switch branches.
Aborting
# 發現此時切換分支失敗,讓你在切換分支之前,先提交更改或存儲更改。
# 下面我們進行存儲更改
# 4.現在想要切換分支,但是還不想要提交之前的修改工作,所以存儲修改。
# 將新的Git存儲推送到棧上,運行 git stash 或 git stash push
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git stash
warning: LF will be replaced by CRLF in stash.txt.
The file will have its original line endings in your working directory
Saved working directory and index state WIP on dev: 4f69dbb 第3次提交,在dev分支新增stash.txt文件
# 5.查看Git存儲棧中的內容,可以看到一條Git存儲內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git stash list
stash@{0}: WIP on dev: 4f69dbb 第3次提交,在dev分支新增stash.txt文件
# 6.再次查看工作目錄中文件狀態,可以看到工作目錄是乾淨的,就可以進行分支切換了。
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git status
On branch dev
nothing to commit, working tree clean
# 7.此時我們先來查看一下歷史提交記錄的變化
# 沒有變化
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git log --oneline
4f69dbb (HEAD -> dev) 第3次提交,在dev分支新增stash.txt文件
89e03bd (master) 第2次提交,readme.txt文件,v2版本
80add2e 第1次提交,新增readme.txt文件
# 此時提交歷史多了一條HEAD移動記錄,但是commit-id沒有變化。(知道就行了)
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git reflog
4f69dbb (HEAD -> dev) HEAD@{0}: reset: moving to HEAD
4f69dbb (HEAD -> dev) HEAD@{1}: commit: 第3次提交,在dev分支新增stash.txt文件
89e03bd (master) HEAD@{2}: checkout: moving from master to dev
89e03bd (master) HEAD@{3}: commit: 第2次提交,readme.txt文件,v2版本
80add2e HEAD@{4}: commit (initial): 第1次提交,新增readme.txt文件
# 7.切換到master分支。
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git checkout master
Switched to branch 'master'
2)在master
分支工作完成之後,在切換回dev
分支。
# 1.在master分支,查看Git存儲棧中的內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (master)
$ git stash list
stash@{0}: WIP on dev: 4f69dbb 第3次提交,在dev分支新增stash.txt文件
# 我們可以看到在master分支中,也能看到Git存儲棧中的內容。
# 就說明Git存儲棧中的內容可以在不同的分支使用。
# 這裏就不在master分支使用了
# 2.切換到dev分支
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (master)
$ git status
On branch master
nothing to commit, working tree clean
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (master)
$ git checkout dev
Switched to branch 'dev'
# 可以看到此時dev分支的工作目錄是乾淨的。
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git status
On branch dev
nothing to commit, working tree clean
# 3.把Git存儲棧中的內容進行恢復
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git stash list
stash@{0}: WIP on dev: 4f69dbb 第3次提交,在dev分支新增stash.txt文件
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git stash apply stash@{0}
On branch dev
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: stash.txt
no changes added to commit (use "git add" and/or "git commit -a")
# 4.查看stash.txt文件內容,可以看到內容恢復了
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ cat stash.txt
stash.txt v1
stash.txt v2
3)刪除Git存儲棧中的內容
# 1.查看Git存儲棧中的內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git stash list
stash@{0}: WIP on dev: 4f69dbb 第3次提交,在dev分支新增stash.txt文件
# 我們可以看到Git存儲棧中的內容,不會自動刪除,是需要手動進行刪除的。
# 2.刪除Git存儲棧中的內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git stash drop stash@{0}
Dropped stash@{0} (00e9eb7b2ae3d1264656e75161b7c3f83b034282)
# 3.再次查看Git存儲棧中的內容,可以看到沒有任何存儲的內容了。
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/gitstash (dev)
$ git stash list
在工作中通常使用git stash pop
命令,代替git stash apply
和git stash drop
命令。
一般我們在實際工作中,不要把這個Git存儲棧弄得很複雜,只建議存儲一個元素,用完就刪除。
參考: