超级面板
文章目录
最新文章
最近更新
文章分类
标签列表
文章归档

Git stash - 暂存操作

当正在进行某项开发任务过程中,突然有另一件紧急的事情需要处理,比如有线上问题,这个时候,当前代码并没有开发完成不想提交, git stash 命令就是一个解决此问题的方法。

stash 命令可以把当前未提交的内容给暂存起来,还原到上次提交的状态,然后可以在任意合适的时刻,以及任意分支,把这些变动给还原回来。

本文看一下 git stash 相关的命令。注意,本文中示例 $ 开头的表示执行的命令,其他内容为命令的输出。

git stash

git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
2 [-u|--include-untracked] [-a|--all] [-m|--message <message>]
2 [--pathspec-from-file=<file> [--pathspec-file-nul]]
2 [--] [<pathspec>…​]]

首先进入一个 git 仓库,使用 git status 查看一下状态:

$ cd test
$ git status

# 输出
On branch test
nothing to commit, working tree clean

可以看到此时工作区是干净的,没有任何变更,尝试修改一个文件:

$ echo 'stashed change' > README.md
$ git status

On branch test
Untracked files:
(use "git add <file>..." to include in what will be committed)
modified: README.md

nothing added to commit but untracked files present (use "git add" to track)

这个时候,有新的工作需要处理,执行 git stash 来暂存文件:

$ git stash

Saved working directory and index state WIP on test: 3ef7d58 release 1.0

$ git status
On branch test
nothing to commit, working tree clean

可以看到此时工作区已经回到了编辑前的干净状态,这个时候就可以进行其他的修改了。

使用 -m 命令可以在stash 时设置message:

$ git stash -m "debug code"

$ git stash list

stash@{0}: On test: debug code
stash@{1}: WIP on test: 3ef7d58 release 1.0
stash@{2}: WIP on test: 3ef7d58 release 1.0

默认情况下,stash 只会保存已修改和暂存的 已追踪文件,也就是说未被追踪过的文件是无法保存的,下面尝试新建一个文件来保存:

$ touch newfile

$ git stash

No local changes to save

$ git status

On branch test
Untracked files:
(use "git add <file>..." to include in what will be committed)
newfile

nothing added to commit but untracked files present (use "git add" to track)

可以看到新建的文件无法被存储,这个时候可以加上 --include-untracked-u 参数,可以看到,此时新增加的文件也被 stash 暂存了:

$ git stash -u

Saved working directory and index state WIP on test: 3ef7d58 release 1.0

$ git status

On branch test
nothing to commit, working tree clean

git stash list

git stash list [<log-options>]

git stash list 用于查看当前的 stash 都存储了哪些内容:

$ git stash list

stash@{0}: WIP on test: 3ef7d58 release 1.0
stash@{1}: WIP on test: 3ef7d58 release 1.0
stash@{2}: WIP on test: 3ef7d58 release 1.0

每个保存的 stash 都有个 name,如上命令的输出看到,格式为stash@{<name>},stash 使用了栈的存储结构,所以数字越小的是越近保存的,如 stash@{0} 是最新保存的,stash@{2} 是最早保存的。

从上面的语法可以看出 stash list 命令还支持 git log 命令的参数,比如使用 --pretty=oneline 命令查看 stash 的详细改动:

$ git stash list --pretty=oneline

e2a114ca7692a1415b6d97e71dee8935af251a41 (refs/stash) refs/stash@{0}: WIP on test: 3ef7d58 release 1.0
6446c1dffa700c1b603396c19a372ce1cdd63956 refs/stash@{1}: WIP on test: 3ef7d58 release 1.0
e32b6ec77994ada19051586af37b0bc595bd9605 refs/stash@{2}: WIP on test: 3ef7d58 release 1.0

git stash show

git stash show [diff-options] [stash]

git stash show 用于查看 stash 存储的改动,默认展示最近一次的改动:

$ git stash show

README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

如果要看其它的存储,可以加上 stash name

$ git stash list

stash@{0}: WIP on test: 3ef7d58 release 1.0

$ git stash show stash@{0}

README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

从上面的语法可以看出 stash show 命令还支持 git diff 命令的参数,比如使用 -p 命令,可以查看 stash 的详细改动:

$ git stash show -p

diff --git a/README.md b/README.md
index ec3514a..79105b0 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-'test'
+'stashed change version 3'

git stash drop

git stash drop [-q|--quiet] [stash]

git stash drop 用于删除 stash 中的某个存储:

$ git stash list

stash@{0}: WIP on test: 3ef7d58 release 1.0
stash@{1}: WIP on test: 3ef7d58 release 1.0
stash@{2}: WIP on test: 3ef7d58 release 1.0

$ git stash drop stash@{2}
Dropped stash@{2} (e32b6ec77994ada19051586af37b0bc595bd9605)

$ git stash list

stash@{0}: WIP on test: 3ef7d58 release 1.0
stash@{1}: WIP on test: 3ef7d58 release 1.0

git stash apply

git stash apply [--index] [-q|--quiet] [stash]

git stash applygit stash 的反操作,将 stash 保存的状态还原到工作区,也就是还原指定的 stash 的内容:

$ echo 'stashed and restore' > README.md

$ git status

On branch 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: README.md

no changes added to commit (use "git add" and/or "git commit -a")

$ git stash

Saved working directory and index state WIP on test: 3ef7d58 release 1.0

$ git status

On branch test
nothing to commit, working tree clean

$ git stash apply

On branch 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: README.md

no changes added to commit (use "git add" and/or "git commit -a")

从上面的操作可以看出,执行了 git stash apply 后,工作取得状态又还原回 git stash 之前的状态了。

git stash pop

git stash pop [--index] [-q|--quiet] [stash]

git stash popgit stash apply 的作用完全一样,不同点在于 git stash apply 不会stash 中删除还原的 stash,而 git stash pop 从 stash 中删除:

$ git stash list

stash@{0}: WIP on test: 3ef7d58 release 1.0
stash@{1}: WIP on test: 3ef7d58 release 1.0
stash@{2}: WIP on test: 3ef7d58 release 1.0

$ git stash apply
$ git stash list

stash@{0}: WIP on test: 3ef7d58 release 1.0
stash@{1}: WIP on test: 3ef7d58 release 1.0
stash@{2}: WIP on test: 3ef7d58 release 1.0

$ git stash pop
$ git stash list
stash@{0}: WIP on test: 3ef7d58 release 1.0
stash@{1}: WIP on test: 3ef7d58 release 1.0

从上面的例子可以看出 git stash apply 执行后 stash list 没有变化,而 git stash pop 执行后 stash list 里没有了此内容。

git stash clear

git stash clear 用于清除所有 stash 里存储的内容:

$ git stash list
stash@{0}: WIP on test: 3ef7d58 release 1.0

$ git stash clear
$ git stash list
//输出空

可以看到,此时的 stash 已经被清空了。

git stash branch

git stash branch <branchname> [<stash>]

git stash branch 命令会以指定的分支名创建一个新分支,然后从 stash 中 检出存储的内容,然后从 stash 中丢弃保存的内容:

$ git stash list

stash@{0}: WIP on test: 3ef7d58 release 1.0
stash@{1}: WIP on test: 3ef7d58 release 1.0
stash@{2}: WIP on test: 3ef7d58 release 1.0

$ git stash branch test-stash stash@{1}

Switched to a new branch 'test-stash'
On branch test-stash
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: README.md

no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{1} (9a6040c186a91874c6949f5ec29de61b9bcc1014)

$ git stash list

stash@{0}: WIP on test: 3ef7d58 release 1.0
stash@{1}: WIP on test: 3ef7d58 release 1.0
stash@{2}: WIP on test: 3ef7d58 release 1.0

git stash create/store

两个命令不常用,就不总结了,详细可以查看 git 的文档。

参考