名称
git-stash - 将变化藏在一个脏工作区中
概述
git stash list [<日志选项>]
git stash show [-u | --include-untracked | --only-untracked] [<差异选项>] [<暂存>]
git stash drop [-q | --quiet] [<暂存>]
git stash pop [--index] [-q | --quiet] [<暂存>]
git stash apply [--index] [-q | --quiet] [<暂存>]
git stash branch <分支名> [<暂存>]
git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
[-u | --include-untracked] [-a | --all] [(-m | --message) <信息>]
[--pathspec-from-file=<文件> [--pathspec-file-nul]]
[--] [<路径规范>…]]
git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
[-u | --include-untracked] [-a | --all] [<信息>]
git stash clear
git stash create [<信息>]
git stash store [(-m | --message) <信息>] [-q | --quiet] <提交>
描述
当你想记录工作目录和索引的当前状态,但又想回到一个干净的工作目录时,请使用git stash
。 该命令将你的本地修改保存起来,并将工作目录还原为与HEAD
提交相匹配。
这个命令所存储的修改可以用git stash list
列出,用git stash show
检查,用git stash apply
恢复(可能是在不同的提交之上)。 在没有任何参数的情况下调用git stash
等同于git stash push
。 默认情况下,储藏库被列为 "WIP on branchname …",但你可以在创建储藏库时在命令行中给出更多描述性信息。
你最近创建的储藏库被保存在refs/stash
中;旧的储藏库可以在这个引用的引用日志中找到,并且可以使用通常的引用日志语法来命名(例如,stash@{0}
是最近创建的储藏库,stash@{1}
是它之前的储藏库,stash@{2.hours.ago}
也是可以的)。也可以通过指定储藏库的索引来引用储藏库(例如,整数n
等同于stash@{n}
)。
命令
push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [(-m|--message) <信息>] [--pathspec-from-file=<文件> [--pathspec-file-nul]] [--] [<路径规范>…]
将你的本地修改保存到一个新的 "存储条目 "中,并将它们回滚到 HEAD(在工作区和索引中)。 <信息>部分是可选的,它给出了描述和储藏的状态。
为了快速制作快照,你可以省略 "push"。 在这种模式下,非选项参数是不允许的,以防止拼写错误的子命令产生不需要的储藏条目。 这方面的两个例外是stash -p
,它作为stash push -p
的别名,以及为消除歧义允许在双连字符--
之后的路径规范元素。
save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<信息>]
该选项已被弃用,改为 "git stash push"。 它与 "stash push "的不同之处在于,它不能接受路径规范。 取而代之的是,所有非选项的参数都被串联起来,形成储藏消息。
list [<日志选项>]
列出你目前拥有的储藏目录。 每个 "储藏目录 "都列出了它的名字(例如,stash@{0}
是最新的条目,stash@{1}
是之前的条目,等等),条目产生时的分支名称,以及该条目所基于的提交的简短描述。
stash@{0}: WIP on submit: 6ebd0e2...更新 git-stash 文档
stash@{1}: On master: 9cc0589... 添加 git-stash
该命令采用适用于 git log 命令的选项来控制显示的内容和方式。参见 [git-log[1]](https://git-scm.com/docs/git-log/zh_HANS-CN) 。
show [-u|--include-untracked|--only-untracked] [<diff选项>] [<储藏目录>]
显示贮藏中记录的修改,作为贮藏内容与贮藏库条目首次创建时的提交之间的差异。 默认情况下,该命令显示diff统计,但它会接受 "git diff "已知的任何格式(例如,git stash show -p stash@{1}以补丁形式查看第二条最新条目)。 如果没有提供<diff选项>,默认行为将由stash.showStat
和stash.showPatch
配置变量给出。你也可以使用stash.showIncludeUntracked
来设置是否默认启用--include-untracked`。
pop [--index] [-q|--quiet] [<暂存>]
从贮藏库列表中移除一个单一的贮藏状态,并将其应用于当前工作区状态之上,也就是做git stash push
的逆向操作。工作目录必须与索引匹配。
应用状态可能会因为冲突而失败;在这种情况下,它不会被从贮藏库列表中删除。你需要手动解决冲突,并在之后调用 git stash drop。
apply [--index] [-q|--quiet] [<暂存>]
和 pop 一样,但不从贮藏库列表中删除该状态。与pop
不同,<贮藏项>
可以是任何看起来像由stash push
或stash create
创建的提交。
branch <分支名> [<贮藏项>]
创建并检查一个名为 <分支名> 的新分支,从最初创建 <贮藏项> 的提交开始,将 <贮藏项> 中记录的修改应用到新的工作树和索引。 如果成功了,并且<贮藏项>是
stash@{<版本>}形式的引用,那么它将删除<贮藏项>
。
如果你运行 git stash push 的分支发生了足够的变化,以至于 git stash apply 因冲突而失败,那么这就很有用。由于贮藏条目是在运行 git stash 时的 HEAD 提交之上应用的,它没有冲突地恢复了最初的贮藏状态。
清除
删除所有的贮藏条目。直接切断任何联系,而且可能无法恢复(可能的策略见下面的 "例子")。
Drop [-q|--quiet] [<贮藏项>]
从贮藏条目列表中删除一个单一的贮藏条目。
create
创建一个贮藏条目(这是一个普通的提交对象),并返回其对象名称,而不将其存储在引用命名空间的任何地方。 这是为了对脚本有用。 你可能不想用这个命令;可以看看前面的 "push"。
保存
将通过’git stash create'(这是一个悬空的合并提交)创建的特定贮藏库存储在贮藏库引用中,更新贮藏库参考文件。 这是为了对脚本有用。 这条命令可能不是你想要的;见上文"push"。
选项
-a
--all
这个选项只对push
和save
命令有效。
所有被忽略的和未被追踪的文件也被贮藏起来,然后用git clean
来清理。
-u
--include-untracked
--no-include-untracked
当与push
和save
命令一起使用时,所有未被追踪的文件也被贮藏起来,然后用git clean
来清理。
当与show
命令一起使用时,显示贮藏库条目中未被追踪的文件作为差异的一部分。
--only-untracked
这个选项只对show
命令有效。
只显示贮藏库条目中未被追踪的文件作为差异的一部分。
--index
这个选项只对pop
和apply
命令有效。
不仅试图恢复工作区的变化,而且恢复索引的变化。然而,这可能会在出现冲突时失败(这些冲突被存储在索引中,因此你不能再按原来的方式应用这些变化)。
-k
--keep-index
--no-keep-index
这个选项只对push
和save
命令有效。
所有已经添加到索引中的变化都保持原样。
-p
--patch
这个选项只对push
和save
命令有效。
交互式地从 HEAD 和工作区之间的差异中选择要存储的内容。 藏匿条目的构造是这样的:它的索引状态与你仓库的索引状态相同,它的工作区只包含你交互选择的变化。 被选中的修改会从你的工作区中回滚。参见 [git-add[1]](https://git-scm.com/docs/git-add/zh_HANS-CN) 中的 '互动模式' 一节,了解如何操作--patch
模式。
选项 --patch 意味着 --keep-index。 你可以使用 --no-keep-index 来覆盖它。
-S
--staged
这个选项只对push
和save
命令有效。
只存放当前分阶段的修改。这类似于基本的git commit
,只不过是将状态提交到贮藏室而不是当前分支。
--patch
选项要优先于这个选项。
--pathspec-from-file=
这个选项只对push
命令有效。
Pathspec在 <文件> 中传递,而不是在命令行参数中传递。如果 <文件> 正好是 -,则使用标准输入。路径规范元素由 LF 或 CR/LF 分隔。可以引用配置变量 core.quotePath 的路径规范元素(请参见 git-config[1])。另请参见 --pathspec-file-nul 和全局 --literal-pathspecs。
--pathspec-file-nul
这个选项只对push
命令有效。
只有在使用 --pathspec-from-file 选项时才有意义。指定路径元素用 NUL 字符分隔,所有其他字符都按字面意思(包括换行符和引号)表示。
-q
--quiet
这个选项只对apply
、drop、pop、push、save、store
命令有效。
静默,压制反馈信息。
--
这个选项只对push
命令有效。
为了消除歧义,将路径规范与选项分开。
…
这个选项只对push
命令有效。
新的贮藏条目只记录了符合路径规范文件的修改状态。 然后索引条目和工作区文件也被回滚到 HEAD 中的状态,只留下不符合路径规范的文件。
更多细节请参见 [gitglossary[7]](https://git-scm.com/docs/gitglossary/zh_HANS-CN) 中的 路径规范 条目。
这个选项只对apply
、branch、drop、pop、show
命令有效。
一个形式为stash@{<版本>}的引用。如果没有给出<贮藏项>,则假定是最新的储藏库(即
stash@{0})。
讨论
一个贮藏库条目被表示为一个提交,它的目录树记录了工作目录的状态,它的第一个父节点是创建该条目时在HEAD
的提交。 第二个父节点的树记录了条目生成时索引的状态,它是HEAD
提交的一个子节点。 祖先图看起来像这样:
.----W
/ /
-----H----I
其中H
是HEAD
提交,I
是记录索引状态的提交,W
是记录工作区状态的提交。
实例
拉进一个脏目录树
当你在做某件事的时候,你得知上游有一些变化可能与你正在做的事情有关。 当你的本地修改与上游的修改不冲突时,一个简单的`git pull’就可以让你继续前进。
然而,在有些情况下,你的本地修改确实与上游修改有冲突,而git pull
拒绝覆盖你的修改。 在这种情况下,你可以把你的进度保存起来,执行一次拉取,然后再解开,像这样:
$ git pull
...
文件 foobar 不是最新的,无法合并。
$ git stash
$ git pull
$ git stash pop
中断的工作流程
当你正在做某件事的时候,你的老板来了,要求你立即修复某件事。 传统上,你会向一个临时分支提交,以储存你的修改,然后返回到你的原始分支进行紧急修复,就像这样:
# ... 嗨骇害 ...
$ git switch -c my_wip
$ git commit -a -m "我待会还得写点东西"
$ git switch master
$ edit emergency fix
$ git commit -a -m "速速修复BUG"
$ git switch my_wip
$ git reset --soft HEAD^
# ... 继续骇入 ...
你可以用’git stash’来简化上述工作,像这样:
# ... 嗨骇害 ...
$ git stash
$ edit emergency fix
$ git commit -a -m "紧急修复"
$ git stash pop
# ... 继续骇入 ...
部分测试提交
当你想把工作区上的改动做两个或更多的提交,并且想在提交前测试每个改动时,你可以使用git stash push --keep-index
:
# ... 嗨骇害 ...
$ git add --patch foo # 仅将第一部分添加到索引中
$ git stash push --keep-index # 将所有其他改动保存到储藏室中
$ edit/build/test first part
$ git commit -m '第一个部分' # 提交完全测试过的改动
$ git stash pop # 准备处理所有其他改动
# ... 重复以上五个步骤,直到剩下一个提交...
$ 编辑/构建/测试剩余部分
$ git commit foo -m '剩余部分'。
保存不相关的变化供将来使用
当你在进行大规模修改时,发现一些不相关的问题,你不想忘记修复,你可以进行修改,将其分阶段,然后使用 git stash push --staged 将其存放起来,以便将来使用。这类似于提交阶段性修改,只是提交的结果是在贮藏库而不是在当前分支。
# ... 嗨骇害 ...
$ git add --patch foo # 将不相关的改动添加到索引中
$ git stash push --staged # 将这些改动保存到储藏库中
# ... 嗨骇害, 完成当前改动 ...
$ git commit -m '大规模测试' # 提交完全测试过的改动
$ git switch fixup-branch # 切换到另一个分支
$ git stash pop # 完成已保存更改的工作
恢复被错误地清除/丢弃的贮藏库条目
如果你错误地丢弃或清除了贮藏库条目,它们无法通过正常的安全机制恢复。 然而,你可以试试下面的咒语,以获得仍在你的版本库中,但无法到达的贮藏库条目列表:
git fsck --unreachable |
grep commit | cut -d -f3 |
xargs git log --merges --no-walk --grep=WIP
评论 (0)