【學了就忘】Git操作 — 48.Git存儲

1、什麼是Git存儲

有時當你在項目的一個分支上,已經工作一段時間後,所有東西都進入了混亂的狀態, 而這時你想要切換到另一個分支做一點別的事情。 問題是,你不想僅僅因爲這點別的事,而把剛剛做了一半的工作進行一次提交。

針對這個問題,可以使用 git stash 命令來解決。(stash:貯藏)

git stash 命令會處理工作目錄的髒狀態,即:根據文件的修改與暫存的改動,然後將未完成的修改保存到一個棧上, 而你可以在任何時候重新應用這些改動(甚至在不同的分支上)。

2、Git存儲的常用命令

  1. git stashgit stash pushgit stash save:保存當前工作進度,會把暫存區和工作區的改動stash(保存)起來。執行完這個命令後,在運行git status命令,就會發現當前工作目錄中有一個乾淨的工作區,沒有任何改動。

    使用git stash save '註釋'可以給存儲的進度添加註釋。

  2. git stash list:顯示Git存儲棧中的進度列表。

  3. 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}

  4. git stash apply [–index] [stash_id]:不刪除恢復的Git存儲,其餘和git stash pop命令一樣。

  5. git stash drop [stash_id]:刪除一個存儲的進度。如果不指定stash_id,則默認刪除最新的存儲進度。

  6. git stash clear:刪除所有存儲的進度。

  7. git stash show:顯示stash的內容具體是什麼,使用方法如 git stash show stash@{0}

  8. 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、常用參數說明

  1. -k:即--keep-index參數:

    在保存進度後,不會將暫存區重置。默認會將暫存區和工作區強制重置。

  2. --patch:會顯示工作區和HEAD的差異。通過對差異文件的編輯,決定在進度中,最終要保存的,工作區的內容。通過編輯差異文件,可以在進度中排除無關內容。

  3. -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 applygit stash drop命令。

一般我們在實際工作中,不要把這個Git存儲棧弄得很複雜,只建議存儲一個元素,用完就刪除。

參考:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章