背景
有时,当你在项目的一部分上已经工作一段时间后,而这时你想要切换到另一个分支做一点别的事情。 问题是,你不想仅仅因为过会儿回到这一点而为做了一半的工作创建一次提交。 针对这个问题的答案是 git stash命令。
git 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 save:
$ 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: 049d0178 added the index file
stash@{1}: WIP on master: c2640151 Revert "added file_size"
stash@{2}: WIP on master: 21d801a5 added number to log
在本例中,有两个之前做的暂存,所以你接触到了三个不同的暂存工作。 可以通过原来 stash 命令的帮助提示中的命令将你刚刚暂存的工作重新应用:git stash apply。 如果想要应用其中一个更旧的暂存,可以通过名字指定它,像这样:git stash apply stash@{2}。 如果不指定一个暂存,Git 认为指定的是最近的暂存:
$ git stash apply
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: index.html
# modified: lib/simplegit.rb #
可以看到 Git 重新修改了当你暂存时撤消的文件。 也可以运行 git stash pop来应用暂存并从栈上扔掉它。
暂存的丢弃可以运行 git stash drop加上将要移除的暂存的名字来移除它:
$ git stash list
stash@{0}: WIP on master: 049d1078 added the index file
stash@{1}: WIP on master: c2641051 Revert "added file_size"
stash@{2}: WIP on master: 21d810a5 added number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
从暂存创建一个分支
如果暂存了一些工作,在后续重新应用工作时可能会有问题。 如果应用尝试修改刚刚修改的文件,你会得到一个合并冲突并不得不解决它。 如果想要一个轻松的方式来再次测试储藏的改动,可以运行 git stash branch创建一个新分支,检出暂存工作时所在的提交,重新在那应用工作,然后在应用成功后扔掉:
$ git stash branch testchanges
Switched to a new branch "testchanges"
# On branch testchanges
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: lib/simplegit.rb # Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)
这是在新分支轻松恢复暂存工作并继续工作的一个很不错的途径。