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