git stash
有时,当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态, 而这时你想要切换到另一个分支做一点别的事情,或者需要重新拉取远程分支更新的代码。 问题是,你不想仅仅因为过会儿回到这一点而为做了一半的工作创建一次提交。 针对这个问题的答案是 git stash
命令。
贮藏(stash)会处理工作目录的脏的状态——即跟踪文件的修改与暂存的改动——然后将未完成的修改保存到一个栈上, 而你可以在任何时候重新应用这些改动(甚至在不同的分支上)。
如果运行 git status
,可以看到有改动的状态:
$ git status
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
现在想要切换分支,但是还不想要提交之前的工作;所以贮藏修改。 将新的贮藏推送到栈上,运行 git stash
或 git stash push
:
$ git stash
Saved working directory and index state \
"WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")
可以看到工作目录是干净的了:
$ git status
# On branch master
nothing to commit, working directory clean
此时,你可以切换分支并在其他地方工作;你的修改被存储在栈上。 要查看贮藏的东西,可以使用 git stash list
:
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
在本例中,有两个之前的贮藏,所以你接触到了三个不同的贮藏工作。 可以通过原来 stash 命令的帮助提示中的命令将你刚刚贮藏的工作重新应用:git stash apply
。 如果想要应用指定的贮藏,可以通过名字指定它,像这样:git stash apply stash@{2}
。 如果不指定一个贮藏,Git 认为指定的是最近的贮藏:
$ git stash apply
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: index.html
modified: lib/simplegit.rb
no changes added to commit (use "git add" and/or "git commit -a")
可以看到 Git 重新修改了当你保存贮藏时撤消的文件。 在本例中,当尝试应用贮藏时有一个干净的工作目录,并且尝试将它应用在保存它时所在的分支。 并不是必须要有一个干净的工作目录,或者要应用到同一分支才能成功应用贮藏。 可以在一个分支上保存一个贮藏,切换到另一个分支,然后尝试重新应用这些修改。 当应用贮藏时工作目录中也可以有修改与未提交的文件——如果有任何东西不能干净地应用,Git 会产生合并冲突。
文件的改动被重新应用了,但是之前暂存的文件却没有重新暂存。 想要那样的话,必须使用 --index
选项来运行 git stash apply
命令,来尝试重新应用暂存的修改。 如果已经那样做了,那么你将回到原来的位置:
$ git stash apply --index
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
应用选项只会尝试应用贮藏的工作——在堆栈上还有它。 可以运行 git stash drop
加上将要移除的贮藏的名字来移除它:
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
也可以运行 git stash pop
来应用贮藏然后立即从栈上扔掉它。
总结:
常用的stash命令,基本可以满足日常开发需求
# 保存当前未commit的代码
git stash
# 保存当前未commit的代码并添加备注
git stash save "备注的内容"
# 列出stash的所有记录
git stash list
# 删除stash的所有记录
git stash clear
# 应用最近一次的stash
git stash apply
# 应用最近一次的stash,随后删除该记录
git stash pop
# 删除最近的一次stash
git stash drop
# 指定应用代码
git stash apply stash@{1}