当正在进行某项开发任务过程中,突然有另一件紧急的事情需要处理,比如有线上问题,这个时候,当前代码并没有开发完成不想提交, 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 apply
是 git 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 pop
和 git 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 的文档。
参考