常常有这样的事情发生,当你正在进行项目中某一部分的工做,里面的东西处于一个比较杂乱的状态,而你想转到其余分支上进行一些工做。问题是,你不想提交进行了一半的工做,不然之后你没法回到这个工做点。解决这个问题的办法就是git stash
命令。html
“‘储藏”“能够获取你工做目录的中间状态——也就是你修改过的被追踪的文件和暂存的变动——并将它保存到一个未完结变动的堆栈中,随时能够从新应用。git
为了演示这一功能,你能够进入你的项目,在一些文件上进行工做,有可能还暂存其中一个变动。若是你运行 git status
,你能够看到你的中间状态:app
$ git status # 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) # # modified: lib/simplegit.rb #
如今你想切换分支,可是你还不想提交你正在进行中的工做;因此你储藏这些变动。为了往堆栈推送一个新的储藏,只要运行 git stash
:rest
$ 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")
你的工做目录就干净了:code
$ git status # On branch master nothing to commit, working directory clean
这时,你能够方便地切换到其余分支工做;你的变动都保存在栈上。要查看现有的储藏,你可使用 git stash list
:htm
$ 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 默认使用最近的储藏并尝试应用它:get
$ git stash apply # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # # modified: index.html # modified: lib/simplegit.rb #
你能够看到 Git 从新修改了你所储藏的那些当时还没有提交的文件。在这个案例里,你尝试应用储藏的工做目录是干净的,而且属于同一分支;可是一个干净的工做目录和应用到相同的分支上并非应用储藏的必要条件。你能够在其中一个分支上保留一份储藏,随后切换到另一个分支,再从新应用这些变动。在工做目录里包含已修改和未提交的文件时,你也能够应用储藏——Git 会给出归并冲突若是有任何变动没法干净地被应用。it
对文件的变动被从新应用,可是被暂存的文件没有从新被暂存。想那样的话,你必须在运行 git stash apply
命令时带上一个 --index
的选项来告诉命令从新应用被暂存的变动。若是你是这么作的,你应该已经回到你原来的位置:ast
$ 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) # # modified: lib/simplegit.rb #
apply 选项只尝试应用储藏的工做——储藏的内容仍然在栈上。要移除它,你能够运行 git stash drop
,加上你但愿移除的储藏的名字:test
$ 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
来从新应用储藏,同时马上将其从堆栈中移走。
在某些状况下,你可能想应用储藏的修改,在进行了一些其余的修改后,又要取消以前所应用储藏的修改。Git没有提供相似于 stash unapply
的命令,可是能够经过取消该储藏的补丁达到一样的效果:
$ git stash show -p stash@{0} | git apply -R
一样的,若是你沒有指定具体的某个储藏,Git 会选择最近的储藏:
$ git stash show -p | git apply -R
你可能会想要新建一个別名,在你的 Git 里增长一个 stash-unapply
命令,这样更有效率。例如:
$ git config --global alias.stash-unapply '!git stash show -p | git apply -R' $ git stash apply $ #... work work work $ git stash-unapply
若是你储藏了一些工做,暂时不去理会,而后继续在你储藏工做的分支上工做,你在从新应用工做时可能会碰到一些问题。若是尝试应用的变动是针对一个你那以后修改过的文件,你会碰到一个归并冲突而且必须去化解它。若是你想用更方便的方法来从新检验你储藏的变动,你能够运行 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 # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # # modified: lib/simplegit.rb # Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)
这是一个很棒的捷径来恢复储藏的工做而后在新的分支上继续当时的工做。