git stash Documentation

YunAdmin
2024-05-10 / 0 评论 / 86 阅读 / 正在检测是否收录...

名称

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.showStatstash.showPatch配置变量给出。你也可以使用stash.showIncludeUntracked来设置是否默认启用--include-untracked`。

pop [--index] [-q|--quiet] [<暂存>]

从贮藏库列表中移除一个单一的贮藏状态,并将其应用于当前工作区状态之上,也就是做git stash push的逆向操作。工作目录必须与索引匹配。

应用状态可能会因为冲突而失败;在这种情况下,它不会被从贮藏库列表中删除。你需要手动解决冲突,并在之后调用 git stash drop。

apply [--index] [-q|--quiet] [<暂存>]

和 pop 一样,但不从贮藏库列表中删除该状态。与pop不同,<贮藏项>可以是任何看起来像由stash pushstash create创建的提交。

branch <分支名> [<贮藏项>]

创建并检查一个名为 <分支名> 的新分支,从最初创建 <贮藏项> 的提交开始,将 <贮藏项> 中记录的修改应用到新的工作树和索引。 如果成功了,并且<贮藏项>是stash@{<版本>}形式的引用,那么它将删除<贮藏项>

如果你运行 git stash push 的分支发生了足够的变化,以至于 git stash apply 因冲突而失败,那么这就很有用。由于贮藏条目是在运行 git stash 时的 HEAD 提交之上应用的,它没有冲突地恢复了最初的贮藏状态。

清除

删除所有的贮藏条目。直接切断任何联系,而且可能无法恢复(可能的策略见下面的 "例子")。

Drop [-q|--quiet] [<贮藏项>]

从贮藏条目列表中删除一个单一的贮藏条目。

create

创建一个贮藏条目(这是一个普通的提交对象),并返回其对象名称,而不将其存储在引用命名空间的任何地方。 这是为了对脚本有用。 你可能不想用这个命令;可以看看前面的 "push"。

保存

将通过’git stash create'(这是一个悬空的合并提交)创建的特定贮藏库存储在贮藏库引用中,更新贮藏库参考文件。 这是为了对脚本有用。 这条命令可能不是你想要的;见上文"push"。

选项

-a
--all

这个选项只对pushsave命令有效。

所有被忽略的和未被追踪的文件也被贮藏起来,然后用git clean来清理。

-u
--include-untracked
--no-include-untracked

当与pushsave命令一起使用时,所有未被追踪的文件也被贮藏起来,然后用git clean来清理。

当与show命令一起使用时,显示贮藏库条目中未被追踪的文件作为差异的一部分。

--only-untracked

这个选项只对show命令有效。

只显示贮藏库条目中未被追踪的文件作为差异的一部分。

--index

这个选项只对popapply命令有效。

不仅试图恢复工作区的变化,而且恢复索引的变化。然而,这可能会在出现冲突时失败(这些冲突被存储在索引中,因此你不能再按原来的方式应用这些变化)。

-k
--keep-index
--no-keep-index

这个选项只对pushsave命令有效。

所有已经添加到索引中的变化都保持原样。

-p
--patch

这个选项只对pushsave命令有效。

交互式地从 HEAD 和工作区之间的差异中选择要存储的内容。 藏匿条目的构造是这样的:它的索引状态与你仓库的索引状态相同,它的工作区只包含你交互选择的变化。 被选中的修改会从你的工作区中回滚。参见 [git-add[1]](https://git-scm.com/docs/git-add/zh_HANS-CN) 中的 '互动模式' 一节,了解如何操作--patch模式。

选项 --patch 意味着 --keep-index。 你可以使用 --no-keep-index 来覆盖它。

-S
--staged

这个选项只对pushsave命令有效。

只存放当前分阶段的修改。这类似于基本的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

其中HHEAD提交,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

原文出处:https://git-scm.com/docs/git-stash/zh_HANS-CN

0

评论 (0)

取消