参数细节
- show:显示暂存中记录的更改,作为暂存状态与其原始父状态之间的差异。若未指定
<stash>,则显示最新的一个。 - list:列出当前拥有的所有暂存。每个暂存都以名称(如
stash@{0}是最新暂存,stash@{1}是之前的一个)列出,还包含创建暂存时当前分支的名称以及暂存所基于的提交的简短描述。 - pop:从暂存列表中移除一个暂存状态,并将其应用到当前工作树状态的顶部。
- apply:与
pop类似,但不会从暂存列表中移除该状态。 - clear:移除所有暂存状态。注意,这些状态随后将被修剪,可能无法恢复。
- drop:从暂存列表中移除一个暂存状态。若未指定
<stash>,则移除最新的一个,即stash@{0}。否则,<stash>必须是有效暂存日志引用,格式为stash@{<revision>}。 - create:创建一个暂存(这是一个常规提交对象),并返回其对象名称,但不在引用命名空间中存储它。这主要用于脚本。这可能不是你想要使用的命令;参见上述“save”。
- store:将通过
git stash create创建的给定暂存(这是一个悬挂的合并提交)存储在暂存引用中,更新暂存引用日志。这主要用于脚本。这可能不是你想要使用的命令;参见上述“save”。
第26.1节:什么是暂存
在开发项目时,你可能在功能分支更改中途遇到针对主分支的错误。你尚未准备好提交代码,但也不想丢失所做的更改。这时,git stash就派上用场了。 在分支上运行git status以显示未提交的更改:
(master) $ git status
On branch master
Your branch is up-to-date with 'origin/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: business/com/test/core/actions/Photo.c
no changes added to commit (use "git add" and/or "git commit -a")
然后运行git stash将这些更改保存到暂存堆栈中:
(master) $ git stash
Saved working directory and index state WIP on master:
2f2a6e1 Merge pull request #1 from test/test-branch
HEAD is now at 2f2a6e1 Merge pull request #1 from test/test-branch
如果你向工作目录添加了文件,这些文件也可以暂存。你只需先将其暂存。
(master) $ git stash
Saved working directory and index state WIP on master:
(master) $ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
NewPhoto.c
nothing added to commit but untracked files present (use "git add" to track)
(master) $ git stage NewPhoto.c
(master) $ git stash
Saved working directory and index state WIP on master:
(master) $ git status
On branch master
nothing to commit, working tree clean
(master) $
你现在的工作目录已清除所有所做的更改。可以通过重新运行git status来查看:
(master) $ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
要应用最新的暂存,运行git stash apply(另外,你还可以使用git stash pop来应用并移除最后一次暂存的更改):
(master) $ git stash apply
On branch master
Your branch is up-to-date with 'origin/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: business/com/test/core/actions/Photo.c
no changes added to commit (use "git add" and/or "git commit -a")
不过需要注意的是,暂存不会记住你当时所处的分支。在上述示例中,用户是在主分支上进行暂存的。如果他们切换到dev分支,然后运行git stash apply,最后一次暂存会应用到dev分支上。
(master) $ git checkout -b dev
Switched to a new branch 'dev'
(dev) $ git stash apply
On branch dev
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: business/com/test/core/actions/Photo.c
no changes added to commit (use "git add" and/or "git commit -a")
第26.2节:创建暂存
将当前工作目录和索引(也称为暂存区)的状态保存到一个暂存堆栈中:
git stash
要将所有未跟踪的文件也包含在暂存中,可以使用--include-untracked或-u标志:
git stash --include-untracked
要为你的暂存添加一条消息,以便以后更容易识别,可以使用:
git stash save "<whatever message>"
在暂存后保留暂存区的当前状态,可以使用--keep-index或-k标志:
git stash --keep-index
第26.3节:应用并移除暂存
要应用最后一次暂存并将其从堆栈中移除,输入:
git stash pop
要应用特定的暂存并将其从堆栈中移除,输入:
git stash pop stash@{n}
第26.4节:应用暂存而不移除它
应用最后一次暂存,但不将其从堆栈中移除:
git stash apply
或者应用特定的暂存:
git stash apply stash@{n}
第26.5节:查看暂存
显示最后一次暂存中保存的更改:
git stash show
或者查看特定暂存:
git stash show stash@{n}
要查看特定暂存中保存的更改内容,可以使用:
git stash show -p stash@{n}
第26.6节:部分暂存
如果你只想暂存工作集中的某些差异,可以使用部分暂存:
git stash -p
然后交互式选择要暂存的代码块(hunks)。 从版本2.13.0开始,你还可以避免交互模式,使用新的push关键字和路径规范来创建部分暂存:
git stash push -m "My partial stash" -- app.config
第26.7节:列出已保存的暂存
git stash list
这将以倒序时间顺序列出暂存堆栈中的所有暂存。 你会得到一个类似这样的列表:
stash@{0}: WIP on master: 67a4e01 Merge tests into develop
stash@{1}: WIP on master: 70f0d95 Add user role to localStorage on user login
你可以通过其名称引用特定的暂存,例如stash@{1}。
第26.8节:将正在进行的工作转移到另一个分支
如果你在工作时意识到自己处于错误的分支,并且尚未创建任何提交,可以轻松使用暂存将工作转移到正确的分支:
git stash
git checkout correct-branch
git stash pop
记住,git stash pop会应用最后一次暂存并将其从暂存列表中删除。如果你只想将暂存应用到某个分支,而保留暂存列表中的暂存,可以使用:
git stash apply
第26.9节:移除暂存
移除所有暂存:
git stash clear
移除最后一次暂存:
git stash drop
或者移除特定的暂存:
git stash drop stash@{n}
第26.10节:使用checkout应用暂存的一部分
你创建了一个暂存,希望只检出该暂存中的一些文件。
git checkout stash@{0} -- myfile.txt
第26.11节:从暂存中恢复早期更改
要获取运行git stash后的最新暂存,使用:
git stash apply
要查看你的所有暂存,使用:
git stash list
你会得到一个类似这样的列表:
stash@{0}: WIP on master: 67a4e01 Merge tests into develop
stash@{1}: WIP on master: 70f0d95 Add user role to localStorage on user login
使用显示的编号选择要恢复的特定git stash:
git stash apply stash@{2}
第26.12节:交互式暂存
暂存会将你的工作目录的脏状态——即你的已修改跟踪文件和暂存更改——保存到一个未完成更改的堆栈中,你可以在任何时候重新应用这些更改。 仅暂存已修改的文件: 假设你不想暂存已暂存的文件,只想暂存已修改的文件,可以使用:
git stash --keep-index
这将仅暂存已修改的文件。 暂存未跟踪的文件: 暂存从不保存未跟踪的文件,它只暂存已修改和已暂存的文件。所以,如果你需要暂存未跟踪的文件,可以使用:
git stash -u
这将跟踪未跟踪的、已暂存的和已修改的文件。 仅暂存特定的更改: 假设你需要仅暂存文件中的一部分代码,或者仅暂存所有已修改和已暂存文件中的一些文件,可以像这样操作:
git stash --patch
Git不会暂存所有已修改的内容,而是会提示你交互式地选择哪些更改你想暂存,哪些更改你想保留在工作目录中。
第26.13节:恢复丢失的暂存
如果你刚刚弹出它且终端仍然打开,你仍然可以在屏幕上看到git stash pop打印的哈希值:
$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)
(注意,git stash drop也会产生相同的行。) 否则,你可以使用以下方法找到它:
git fsck --no-reflog | awk '/dangling commit/ {print $3}'
这将显示你的提交图中所有不再从任何分支或标签引用的提交的尖端——包括你创建过的每个暂存提交——这些提交都位于该图中。 找到你想要的暂存提交的最简单方法可能是将这个列表传递给gitk:
gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )
这将启动一个仓库浏览器,显示你仓库中每一个提交,无论它是否可达。 你可以将gitk替换为git log --graph --oneline --decorate,如果你更喜欢在控制台上看到一个漂亮的图,而不是单独的GUI应用程序。 要识别暂存提交,请查找类似以下形式的提交消息:
WIP on somebranch: commithash Some old commit message
一旦你知道了你想要的提交的哈希值,就可以将其作为暂存应用:
git stash apply sh_hash
或者你可以使用gitk中的上下文菜单为任何你感兴趣的不可达提交创建分支。 之后,你可以使用所有正常的工具对它们进行任何操作。完成后,只需再次删除这些分支即可。