设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 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
概要
git stash list [<log-options>] git stash show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>] git stash drop [-q | --quiet] [<stash>] git stash pop [--index] [-q | --quiet] [<stash>] git stash apply [--index] [-q | --quiet] [<stash>] git stash branch <branchname> [<stash>] git stash [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>…]] git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet] [-u | --include-untracked] [-a | --all] [<message>] git stash clear git stash create [<message>] git stash store [(-m | --message) <message>] [-q | --quiet] <commit>
描述
当你想要记录工作目录和索引的当前状态,但又想回到一个干净的工作目录时,可以使用 git
stash
。该命令会将你的本地修改暂存起来,并将工作目录恢复到与 HEAD
提交匹配的状态。
通过此命令暂存的修改可以使用 git
stash
list
列出,使用 git
stash
show
检查,并使用 git
stash
apply
恢复(可能在不同的提交之上)。不带任何参数调用 git
stash
等同于 git
stash
push
。暂存默认显示为“WIP on branchname …”,但你可以在创建时在命令行上给出更具描述性的消息。
你创建的最新暂存存储在 refs/stash
中;旧的暂存可以在此引用的 reflog 中找到,并可以使用通常的 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>…]
-
将你的本地修改保存为一个新的 *暂存条目*,并将它们回滚到 HEAD(在工作树和索引中)。<message> 部分是可选的,并提供了与暂存状态一起的描述。
为了快速创建快照,你可以省略“push”。在此模式下,不允许使用非选项参数,以防止拼写错误的子命令创建不需要的暂存条目。两个例外是
stash
-p
,它作为stash
push
-p
的别名,以及 pathspec 元素,它们在双连字符--
后允许用于消除歧义。 - save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]
-
此选项已被弃用,推荐使用 *git stash push*。它与“stash push”的不同之处在于它不能接受 pathspec。相反,所有非选项参数都将连接起来形成暂存消息。
- 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* 已知的任何格式(例如,
git
stash
show
-p
stash@{1}
以补丁形式查看倒数第二个最新条目)。如果没有提供 <diff-option>,则默认行为将由stash.showStat
和stash.showPatch
配置变量给出。你还可以使用stash.showIncludeUntracked
来设置是否默认启用--include-untracked
。 - pop [--index] [-q|--quiet] [<stash>]
-
从暂存列表中移除单个暂存状态,并将其应用到当前工作树状态之上,即执行
git
stash
push
的逆操作。工作目录必须与索引匹配。应用状态时可能会因冲突而失败;在这种情况下,它不会从暂存列表中移除。你需要手动解决冲突,然后手动调用
git
stash
drop
。 - apply [--index] [-q|--quiet] [<stash>]
-
与
pop
类似,但不会从暂存列表中移除状态。与pop
不同,<stash> 可以是任何看起来像由stash
push
或stash
create
创建的提交。 - branch <branchname> [<stash>]
-
创建一个名为 <branchname> 的新分支并切换到该分支,该分支从 <stash> 最初创建时的提交开始,将 <stash> 中记录的更改应用到新的工作树和索引。如果成功,并且 <stash> 是
stash@{
<revision>}
形式的引用,则它会删除 <stash>。如果运行
git
stash
push
的分支变化很大,导致git
stash
apply
因冲突而失败,此命令会很有用。由于暂存条目是在运行git
stash
时 HEAD 所在的提交之上应用的,因此它会恢复最初暂存的状态,没有冲突。 - clear
-
移除所有暂存条目。请注意,这些条目随后将受制于修剪,并且可能无法恢复(有关可能的策略,请参阅下面的 *示例*)。
- drop [-q|--quiet] [<stash>]
-
从暂存条目列表中移除单个暂存条目。
- create
-
创建一个暂存条目(它是一个普通的提交对象)并返回其对象名称,而不在 ref 命名空间的任何位置存储它。这旨在对脚本有用。这可能不是你想要使用的命令;请参阅上面的“push”命令。
- store
-
将通过 *git stash create* 创建的给定暂存(它是一个悬空合并提交)存储在暂存引用中,更新暂存 reflog。这旨在对脚本有用。这可能不是你想要使用的命令;请参阅上面的“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] 的“交互模式”部分,了解如何操作
--patch
模式。--patch
选项隐含--keep-index
。你可以使用--no-keep-index
覆盖此设置。 - -S
- --staged
-
此选项仅对
push
和save
命令有效。仅暂存当前已暂存的更改。这类似于基本的
git
commit
,只是状态被提交到暂存而不是当前分支。--patch
选项优先于此选项。 - --pathspec-from-file=<file>
-
此选项仅对
push
命令有效。pathspec 通过 <file> 传递,而不是命令行参数。如果 <file> 恰好是
-
,则使用标准输入。pathspec 元素由 LF 或 CR/LF 分隔。pathspec 元素可以像配置变量core.quotePath
所解释的那样引用(请参阅 git-config[1])。另请参阅--pathspec-file-nul
和全局--literal-pathspecs
。 - --pathspec-file-nul
-
此选项仅对
push
命令有效。仅在与
--pathspec-from-file
一起使用时有意义。pathspec 元素用 NUL 字符分隔,所有其他字符都按字面意义处理(包括换行符和引号)。 - -q
- --quiet
-
此选项仅对
apply
、drop
、pop
、push
、save
、store
命令有效。安静模式,抑制反馈消息。
- --
-
此选项仅对
push
命令有效。将 pathspec 与选项分开,以消除歧义。
- <pathspec>…
-
此选项仅对
push
命令有效。新的暂存条目仅记录与 pathspec 匹配的文件的修改状态。索引条目和工作树文件也仅针对这些文件回滚到 HEAD 中的状态,不匹配 pathspec 的文件则保持不变。
有关更多详细信息,请参阅 gitglossary[7] 中的 pathspec 条目。
- <stash>
-
此选项仅对
apply
、branch
、drop
、pop
、show
命令有效。形式为
stash@{
<revision>}
的引用。当未给出 <stash> 时,默认使用最新的暂存(即stash@{0}
)。
讨论
暂存条目表示为一个提交,其树记录了工作目录的状态,其第一个父级是创建条目时 HEAD
处的提交。第二个父级的树记录了创建条目时索引的状态,并且它成为 HEAD
提交的子级。祖先图如下所示
.----W / / -----H----I
其中 H
是 HEAD
提交,I
是记录索引状态的提交,W
是记录工作树状态的提交。
示例
- 拉取到脏树
-
当你在进行某项工作时,你得知上游有一些可能与你正在做的事情相关的更改。如果你的本地更改与上游的更改不冲突,一个简单的
git
pull
就可以让你继续进行。但是,在某些情况下,你的本地更改与上游更改确实冲突,并且
git
pull
拒绝覆盖你的更改。在这种情况下,你可以暂存你的更改,执行拉取,然后解除暂存,像这样$ 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 ...
- 测试部分提交
-
当你想从工作树中的更改创建两个或更多提交,并且在提交之前测试每个更改时,可以使用
git
stash
push
--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'
-
当你在进行大量更改时,发现一些不相关的、你不想忘记修复的问题,你可以进行更改,暂存它们,然后使用
git
stash
push
--staged
将它们暂存起来以备将来使用。这类似于提交已暂存的更改,只是提交最终位于暂存区而不是当前分支上。# ... 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.showIncludeUntracked
-
如果此项设置为 true,
git
stash
show
命令将显示暂存条目中的未跟踪文件。默认为 false。请参阅 git-stash[1] 中 *show* 命令的描述。 - stash.showPatch
-
如果此项设置为 true,不带选项的
git
stash
show
命令将以补丁形式显示暂存条目。默认为 false。请参阅 git-stash[1] 中 *show* 命令的描述。 - stash.showStat
-
如果此项设置为 true,不带选项的
git
stash
show
命令将显示暂存条目的 diffstat。默认为 true。请参阅 git-stash[1] 中 *show* 命令的描述。