设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
-
2.55.0
2026-06-29
-
2.54.0
2026-04-20
- 2.53.0 无变更
-
2.52.0
2025-11-17
- 2.51.1 → 2.51.2 无更改
-
2.51.0
2025-08-18
- 2.43.1 → 2.50.1 无更改
-
2.43.0
2023-11-20
- 2.42.1 → 2.42.4 无更改
-
2.42.0
2023-08-21
- 2.39.1 → 2.41.3 无变更
-
2.39.0
2022-12-12
- 2.38.1 → 2.38.5 无更改
-
2.38.0
2022-10-02
- 2.35.1 → 2.37.7 无更改
-
2.35.0
2022-01-24
- 2.32.1 → 2.34.8 无更改
-
2.32.0
2021-06-06
- 2.31.1 → 2.31.8 无更改
-
2.31.0
2021-03-15
- 2.26.1 → 2.30.9 无变更
-
2.26.0
2020-03-22
- 2.24.1 → 2.25.5 无变更
-
2.24.0
2019-11-04
- 2.23.1 → 2.23.4 无更改
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 无更改
-
2.22.0
2019-06-07
- 2.17.1 → 2.21.4 无变更
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
- 2.15.4 无更改
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
-
2.12.5
2017-09-22
-
2.11.4
2017-09-22
- 2.8.6 → 2.10.5 无变更
-
2.7.6
2017-07-30
- 2.1.4 → 2.6.7 无变更
-
2.0.5
2014-12-17
概要
gitstashlist[<log-options>]gitstashshow[-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]gitstashdrop[-q|--quiet] [<stash>]gitstashpop[--index] [-q|--quiet] [<stash>]gitstashapply[--index] [-q|--quiet] [--label-ours=<label>] [--label-theirs=<label>] [--label-base=<label>] [<stash>]gitstashbranch<branchname> [<stash>]gitstash[push] [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all] [(-m|--message) <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>…]gitstashsave[-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all] [<message>]gitstashcleargitstashcreate[<message>]gitstashstore[(-m|--message) <message>] [-q|--quiet] <commit>gitstashexport(--to-ref<ref>) [<stash>…]gitstashimport<commit>
描述
当你想要记录工作目录和索引的当前状态,但又想回到一个干净的工作目录时,请使用 git stash。该命令会保存你的本地修改,并回退工作目录以匹配 HEAD 提交。
此命令储藏的修改可以使用 git stash list 列出,使用 git stash show 查看,并使用 git stash apply 恢复(可能是在不同的提交之上)。不带任何参数调用 git stash 等同于 git stash push。储藏项默认列为 "WIP on <branchname> …",但在创建时,你可以在命令行中提供更具描述性的信息。
你创建的最新储藏项存储在 refs/stash 中;较旧的储藏项可以在该引用的引用日志(reflog)中找到,并可以使用通常的引用日志语法进行命名(例如 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) <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]-
将你的本地修改保存到一个新的储藏项(stash entry),并将它们回退到
HEAD(在工作树和索引中)。<message> 部分是可选的,用于提供储藏状态的描述。为了快速制作快照,你可以省略 "push"。在这种模式下,路径规格(pathspec)元素只允许出现在双连字符
--之后,以防止拼写错误的子命令创建出不想要的储藏项。 save[-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]-
此选项已被弃用,建议使用 git stash push。它与 "stash push" 的区别在于它不能接收路径规格。相反,所有非选项参数会被连接起来以形成储藏信息。
list[<log-options>]-
列出你当前拥有的储藏项。每个储藏项都列出了其名称(例如
stash@{0}是最新条目,stash@{1}是上一个,等等)、创建条目时所在的当前分支名称,以及该条目所基于的提交的简短描述。stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation stash@{1}: On master: 9cc0589... Add git-stash该命令接受适用于 git log 命令的选项,以控制显示的内容和方式。请参见 git-log[1]。
show[-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]-
以储藏内容与创建储藏项时原始提交之间的差异形式,显示记录在储藏项中的更改。默认情况下,该命令显示差异统计(diffstat),但它接受任何 git diff 已知的格式(例如,
gitstashshow-pstash@{1}以补丁格式查看倒数第二个条目)。如果没有提供 <diff-option>,默认行为将由stash.showStat和stash.showPatch配置变量决定。你还可以使用stash.showIncludeUntracked来设置是否默认启用--include-untracked。 pop[--index] [-q|--quiet] [<stash>]-
从储藏列表中移除单个储藏状态,并将其应用到当前工作树状态之上,即执行
gitstashpush的逆操作。工作目录必须与索引匹配。应用该状态可能会失败并产生冲突;在这种情况下,它不会从储藏列表中移除。你需要手动解决冲突,并在之后手动调用
gitstashdrop。 apply[--index] [-q|--quiet] [<stash>]-
类似于
pop,但不会从储藏列表中移除该状态。与pop不同,<stash> 可以是任何看起来是由stashpush或stashcreate创建的提交。 branch<branchname> [<stash>]-
创建并切换到一个名为 <branchname> 的新分支,该分支从最初创建 <stash> 时的提交开始,并将 <stash> 中记录的更改应用到新的工作树和索引中。如果成功,且 <stash> 是
stash@{<revision>}形式的引用,则删除该 <stash>。这在运行
gitstashpush的分支已经发生了足够大的变化,导致gitstashapply因冲突而失败时非常有用。由于储藏项是应用在运行gitstash时作为 HEAD 的提交之上,它可以在无冲突的情况下恢复最初储藏的状态。 clear-
移除所有储藏项。请注意,这些条目随后将受修剪(pruning)影响,且可能无法恢复(请参阅下方的示例以获取可能的策略)。
drop[-q|--quiet] [<stash>]-
从储藏项列表中移除单个储藏项。
create-
创建一个储藏项(这是一个常规提交对象)并返回其对象名,而不将其存储在引用命名空间中的任何位置。这旨在供脚本使用。这可能不是你想要使用的命令;请参阅上面的 "push"。
store-
将通过 git stash create 创建的给定储藏项(这是一个悬空的合并提交)存储在 stash 引用中,并更新 stash 引用日志。这旨在供脚本使用。这可能不是你想要使用的命令;请参阅上面的 "push"。
export(--print|--to-ref<ref> ) [<stash>...]-
将指定的储藏项(如果未指定,则为全部)导出为一系列提交,这些提交可以使用正常的获取(fetch)和推送(push)机制进行传输,然后使用
import子命令导入。 import<commit>-
从指定的提交中导入指定的储藏项(该提交必须是由
export创建的),并将它们添加到储藏列表中。要替换现有的储藏项,请先使用clear。
选项
-a--all-
此选项仅对
push和save命令有效。所有被忽略和未追踪的文件也会被储藏,然后通过
gitclean清理掉。 -u--include-untracked--no-include-untracked-
当与
push和save命令一起使用时,所有未追踪的文件也会被储藏,然后通过gitclean清理掉。当与
show命令一起使用时,将储藏项中的未追踪文件显示为差异的一部分。 --only-untracked-
此选项仅对
show命令有效。仅将储藏项中的未追踪文件显示为差异的一部分。
--index-
此选项仅对
pop和apply命令有效。尝试恢复的不仅仅是工作树的更改,还有索引的更改。但是,当你遇到冲突时(冲突存储在索引中,因此你无法再按原样应用更改),这可能会失败。
--label-ours=<label>--label-theirs=<label>--label-base=<label>-
这些选项仅对
apply命令有效。在冲突标记中使用给定的标签,而不是默认的 "Updated upstream"、"Stashed changes" 和 "Stash base"。
--label-base仅在 merge.conflictStyle=diff3 时有效。 -k--keep-index--no-keep-index-
此选项仅对
push和save命令有效。所有已添加到索引的更改将保持不变。
-p--patch-
此选项仅对
push和save命令有效。交互式地选择 HEAD 和工作树之间差异的代码块(hunk)进行储藏。储藏项的构建方式是其索引状态与你的仓库索引状态相同,且其工作树仅包含你交互式选择的更改。所选的更改随后会从你的工作树中回退。请参阅 git-add[1] 的“交互式模式”部分,了解如何操作
--patch模式。--patch选项隐含了--keep-index。你可以使用--no-keep-index来覆盖它。 -U<n>--unified=<n>-
生成带有 <n> 行上下文的 diff。上下文行数默认为
diff.context,如果未设置该配置变量,则默认为 3。(由于历史原因,不带 <n> 的-U被静默接受为-p的同义词)。 --inter-hunk-context=<n>-
在差异块之间显示上下文,最多达指定行数 <number>,从而合并彼此接近的块。默认为
diff.interHunkContext,如果未设置配置选项则为 0。 -S--staged-
此选项仅对
push和save命令有效。仅储藏当前暂存的更改。这类似于基础的
gitcommit,只是状态被提交到 stash 而不是当前分支。--patch选项的优先级高于此选项。 --pathspec-from-file=<file>-
此选项仅对
push命令有效。路径规格从 <file> 中传递,而不是从命令行参数。如果 <file> 正好是
-,则使用标准输入。路径规格元素以 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命令有效。安静模式,抑制反馈消息。
--print-
此选项仅对
export命令有效。创建代表所导出储藏项的提交链,而不将其存储在引用命名空间中的任何位置,并将对象 ID 打印到标准输出。这是为脚本设计的。
--to-ref-
此选项仅对
export命令有效。创建代表所导出储藏项的提交链,并将其存储在指定的引用中。
---
此选项仅对
push命令有效。将路径规格与选项隔开,用于消除歧义。
- <pathspec>...
-
此选项仅对
push命令有效。新的储藏项仅记录匹配路径规格的文件的修改状态。随后,索引条目和工作树文件也会仅针对这些文件回退到 HEAD 中的状态,而不匹配路径规格的文件保持不变。
有关更多详细信息,请参阅 gitglossary[7] 中的 pathspec 条目。
- <stash>
-
此选项仅对
apply,branch,drop,pop,show和export命令有效。stash@{<revision>}形式的引用。当未给出 <stash> 时,假定为最新的储藏项(即stash@{0})。
讨论
储藏项表示为一个提交,其树记录了工作目录的状态,其第一个父提交是创建该条目时 HEAD 处的提交。第二个父提交的树记录了创建条目时的索引状态,并使其成为 HEAD 提交的子提交。其祖先图如下所示
.----W
/ /
-----H----I
其中 H 是 HEAD 提交,I 是记录索引状态的提交,W 是记录工作树状态的提交。
示例
- 拉取到脏工作树
-
当你进行到一半时,了解到有上游更改可能与你正在做的事情相关。当你的本地更改与上游更改不冲突时,简单的
gitpull即可让你继续前进。然而,在某些情况下,你的本地更改确实与上游更改冲突,并且
gitpull拒绝覆盖你的更改。在这种情况下,你可以储藏你的更改,执行拉取,然后取消储藏,如下所示$ git pull ... file foobar not up to date, cannot merge. $ git stash $ git pull $ git stash pop
- 中断的工作流
-
当你在进行某项工作时,你的老板进来说需要立即修复某些问题。按照传统方式,你会将更改提交到一个临时分支以保存,然后回到原始分支进行紧急修复,如下所示
# ... hack hack hack ... $ git switch -c my_wip $ git commit -a -m "WIP" $ git switch master $ edit emergency fix $ git commit -a -m "Fix in a hurry" $ git switch my_wip $ git reset --soft HEAD^ # ... continue hacking ...
你可以使用 git stash 来简化上述操作,如下所示
# ... hack hack hack ... $ git stash $ edit emergency fix $ git commit -a -m "Fix in a hurry" $ git stash pop # ... continue hacking ...
- 测试部分提交
-
当你想要从工作树的更改中进行两次或多次提交,并且希望在提交前测试每个更改时,可以使用
gitstashpush--keep-index# ... hack hack hack ... $ git add --patch foo # add just first part to the index $ git stash push --keep-index # save all other changes to the stash $ edit/build/test first part $ git commit -m 'First part' # commit fully tested change $ git stash pop # prepare to work on all other changes # ... repeat above five steps until one commit remains ... $ edit/build/test remaining parts $ git commit foo -m 'Remaining parts'
-
当你正进行大规模更改时,发现了一些无关的问题,不想忘记修复,你可以进行这些更改、暂存它们,然后使用
gitstashpush--staged将它们储藏起来以备后用。这类似于提交已暂存的更改,只是提交最终是在 stash 中,而不是在当前分支上。# ... hack hack hack ... $ git add --patch foo # add unrelated changes to the index $ git stash push --staged # save these changes to the stash # ... hack hack hack, finish current changes ... $ git commit -m 'Massive' # commit fully tested changes $ git switch fixup-branch # switch to another branch $ git stash pop # to finish work on the saved changes
- 恢复被错误清除/删除的储藏项
-
如果你错误地删除了或清除了储藏项,它们无法通过常规安全机制恢复。但是,你可以尝试以下咒语来获取仍在你仓库中但不再可达的储藏项列表
git fsck --unreachable | grep commit | cut -d\ -f3 | xargs git log --merges --no-walk --grep=WIP
配置
本节中以下所有内容均从 git-config[1] 文档中选择性地包含。内容与彼处相同:
stash.index-
如果设置为 true,
gitstashapply和gitstashpop的行为将如同提供了--index一样。默认值为 false。 stash.showIncludeUntracked-
如果设置为 true,
gitstashshow命令将显示储藏项的未追踪文件。默认值为 false。 stash.showPatch-
如果设置为 true,不带选项的
gitstashshow命令将以补丁格式显示储藏项。默认值为 false。 stash.showStat-
如果设置为 true,不带选项的
gitstashshow命令将显示储藏项的差异统计。默认值为 true。