directory search
Guides gitattributes giteveryday gitglossary gitignore gitmodules gitrevisions gittutorial gitworkflows Administration git archive git bundle git clean git filter-branch git fsck git gc git instaweb git reflog Basic Snapshotting git add git commit git diff git mv git reset git rm git status Branching and Merging git branch git checkout git log git merge git mergetool git stash git tag Debugging git bisect git blame git grep Email git am git format-patch git request-pull git send-email External Systems git fast-import git svn Getting and Creating Projects git clone git init Git git annotate git archimport git bisect-lk2009 git check-attr git check-mailmap git check-ref-format git checkout-index git cherry git citool git column git credential git credential-cache git credential-store git cvsexportcommit git cvsimport git cvsserver git diff-files git diff-tree git difftool git fast-export git fetch-pack git fmt-merge-msg git get-tar-commit-id git gui git http-backend git http-fetch git http-push git imap-send git index-pack git interpret-trailers git ls-remote git ls-tree git mailinfo git mailsplit git merge-file git merge-index git merge-one-file git merge-tree git mktag git mktree git name-rev git notes git p4 git pack-objects git pack-redundant git pack-refs git parse-remote git patch-id git prune git prune-packed git quiltimport git receive-pack git remote-ext git remote-fd git remote-testgit git repack git replace git rerere git send-pack git sh-i18n git sh-setup git shell git show-branch git show-index git stripspace git unpack-file git unpack-objects git upload-archive git upload-pack git var git verify-commit git verify-tag git whatchanged git worktree Inspection and Comparison git describe git shortlog git show Miscellaneous api credentials api index gitcli gitcore tutorial gitcredentials gitcvs migration gitdiffcore githooks gitk gitnamespaces gitremote helpers gitrepository layout gitsubmodules gittutorial 2 gitweb gitweb.conf pack format User Manual Patching git apply git cherry-pick git rebase git revert Plumbing Commands git cat-file git check-ignore git commit-tree git count-objects git diff-index git for-each-ref git hash-object git ls-files git merge-base git read-tree git rev-list git rev-parse git show-ref git symbolic-ref git update-index git update-ref git verify-pack git write-tree Server Admin git daemon git update-server-info Setup and Config git git config git help Sharing and Updating Projects git fetch git pull git push git remote git submodule
characters

Name

git-stash  - 将变化存储在脏的工作目录中

概要

git stash list [<options>]git stash show [<stash>]git stash drop [-q|--quiet] [<stash>]git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]git stash branch <branchname> [<stash>]git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]             [-u|--include-untracked] [-a|--all] [<message>]git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]             [-u|--include-untracked] [-a|--all] [-m|--message <message>]]             [--] [<pathspec>…]]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 applygit stash没有任何参数的调用相当于git stash save。默认情况下,存储列为“WIP on branchname...”,但在创建存储时,可以在命令行上提供更多描述性消息。

您创建的最新储藏器存储在refs/stash; 旧的存储在这个引用的reflog中可以找到,并且可以使用通常的reflog语法来命名(例如stash@{0},最近创建的存储,stash@{1}是之前的存储,stash@{2.hours.ago}也是可能的)。通过指定存储索引也可以引用Stache(例如,整数n等价于stash@{n})。

选项

save -p|--patch-k|--no-keep-index] -u|--include-untracked -q|--quiet   push -p|--patch-k|--no-keep-index] -u|--include-untracked -q|--quiet --

将您的本地修改保存为新的stash entry并将它们回滚到 HEAD(在工作树和索引中)。<message>部分是可选的,并给出说明以及隐藏状态。

为了快速制作快照,您可以省略“推送”。在此模式下,不允许使用非选项参数来防止拼写错误的子命令产生不需要的存储条目。对此的两个例外是stash -p作为 alias stash push -p和 pathspecs,它们在--消除歧义之后使用双连字符。

当指定 pathspec 时git stash push,新存储条目仅记录与 pathspec匹配的文件的已修改状态。索引条目和工作树文件然后仅回滚到 HEAD中的这些文件的状态,从而留下与 pathspec 完全不匹配的文件。

如果使用该--keep-index选项,则已添加到索引的所有更改均保持不变。

如果使用该--include-untracked选项,则所有未跟踪的文件也会被隐藏起来,然后进行清理git clean,使工作目录处于非常干净的状态。如果使用该--all选项,则除了未跟踪文件之外,还会隐藏和清除被忽略的文件。

使用--patch,您可以交互式地从 HEAD 和工作树之间的差异中选择区块来隐藏。存储条目的构建方式使其索引状态与存储库的索引状态相同,其工作树仅包含交互式选择的更改。所选的更改将从您的工作树中回滚。请参阅 git-add [1]的“交互模式”部分了解如何操作该--patch模式。

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

list <options>

列出您当前拥有的存储条目。每个stash entry列表都以其名称列出(例如,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 <stash>

显示存储条目中记录的更改,作为隐藏内容和提交首次创建存储条目时的提交之间的差异。当没有<stash>给出时,它显示最新的一个。默认情况下,该命令显示diffstat,但它将接受已知的任何格式git diff(例如,git stash show -p stash@{1}以补丁形式查看第二个最新条目)。您可以使用 stash.showStat 和/或 stash.showPatch 配置变量来更改默认行为。

pop --index <stash>

从存储列表中删除一个单独的存储状态并将其应用于当前工作树状态的顶部,即进行反操作git stash save。工作目录必须与索引匹配。

应用状态可能会因冲突而失败; 在这种情况下,它不会从存储列表中删除。您需要git stash drop手动解决冲突,然后手动调用。

如果使用该--index选项,则尝试不仅恢复工作树的更改,而且还恢复索引的更改。但是,如果发生冲突(存储在索引中,因此您不能再像原来那样应用更改),这可能会失败。

当没有<stash>给出时,stash@{0}假定,否则<stash>必须是表格的参考stash@{<revision>}

apply --index <stash>

pop,但不要从存储列表中删除状态。不像pop<stash>可能是任何看起来像由stash saveor 创建的提交stash create

branch <branchname> <stash>

创建并检出<branchname><stash>最初创建的提交开始的新分支,将记录的更改应用<stash>到新的工作树和索引。如果成功了,并且<stash>是表单的参考stash@{<revision>},则会丢弃该表单<stash>。如果没有<stash>给出,则应用最新的一个。

如果您运行的分支由于冲突而git stash save发生了足够多的分支git stash apply失败,这很有用。由于存储条目应用于git stash运行时HEAD提交的顶部,因此它将恢复原始存储状态而不产生冲突。

clear

删除所有的存储条目。请注意,这些条目将会被修剪,并且可能无法恢复(请参阅Examples下面的可能策略)。

drop -q|--quiet

从存储条目列表中删除单个存储条目。如果没有<stash>给出,它将删除最新的一个。即stash@{0},否则<stash>必须是表单的有效存储日志引用stash@{<revision>}

create

创建一个存储条目(这是一个常规的提交对象)并返回它的对象名称,而不将它存储在ref命名空间的任何位置。这旨在用于脚本。这可能不是你想要使用的命令; 见上面的“保存”。

store

将通过git stash create(这是一个悬挂的合并提交)创建的给定的存储存储在存储引用中,更新存储引用日志。这旨在用于脚本。这可能不是你想要使用的命令; 见上面的“保存”。

讨论

存储条目表示为其记录工作目录状态的提交,其第一个父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 checkout -b my_wip
$ git commit -a -m "WIP"$ git checkout master
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"$ git checkout 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 save --keep-index在您想要在工作树中进行两项或更多项提交时使用,并且您希望在提交前测试每项更改:

# ... hack hack hack ...$ git add --patch foo            # add just first part to the index
$ git stash save --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 fsck --unreachable |grep commit | cut -d\  -f3 |xargs git log --merges --no-walk --grep=WIP
Previous article: Next article: