git-stash - 将在脏的工作目录中的更改暂存起来
git stash list [<options>]
git stash show [<options>] [<stash>]
git stash drop [-q|--quiet] [<stash>]
git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
git stash branch <branchname> [<stash>]
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 apply
恢复(可能在其他提交之上)。不带任何参数调用git stash
等同于git stash push
。默认情况下,存储项被列为“分支名称上的WIP”,但是在创建存储项时,您可以在命令行上提供更具描述性的消息。
您创建的最新存储存储在refs/stash中; 在该引用的引用日志中可以找到较旧的存储,并且可以使用常规的引用日志语法进行命名(例如stash@{0}是最近创建的存储库,stash@{1}是之前创建的存储库,stash@{2.hours.ago}也有可能)。 还可以通过指定存储索引来引用存储(例如,整数n等于stash@{n})。
push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--] [<pathspec>…]
Save your local modifications to a new stash entry and roll them back to HEAD (in the working tree and in the index). The <message> part is optional and gives the description along with the stashed state.
将本地修改保存到新的存储条目,然后将其回滚到HEAD(在工作树和索引中)。 <message>部分是可选的,并提供说明以及隐藏状态。
For quickly making a snapshot, you can omit "push". In this mode, non-option arguments are not allowed to prevent a misspelled subcommand from making an unwanted stash entry. The two exceptions to this are stash -p
which acts as alias for stash push -p
and pathspecs, which are allowed after a double hyphen --
for disambiguation.
When pathspec is given to git stash push, the new stash entry records the modified states only for the files that match the pathspec. The index entries and working tree files are then rolled back to the state in HEAD only for these files, too, leaving files that do not match the pathspec intact.
If the --keep-index
option is used, all changes already added to the index are left intact.
If the --include-untracked
option is used, all untracked files are also stashed and then cleaned up with git clean
, leaving the working directory in a very clean state. If the --all
option is used instead then the ignored files are stashed and cleaned in addition to the untracked files.
With --patch
, you can interactively select hunks from the diff between HEAD and the working tree to be stashed. The stash entry is constructed such that its index state is the same as the index state of your repository, and its worktree contains only the changes you selected interactively. The selected changes are then rolled back from your worktree. See the “Interactive Mode” section of git-add[1] to learn how to operate the --patch
mode.
The --patch
option implies --keep-index
. You can use --no-keep-index
to override this.
save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]
This option is deprecated in favour of git stash push. It differs from "stash push" in that it cannot take pathspecs. Instead, all non-option arguments are concatenated to form the stash message.
list [<options>]
List the stash entries that you currently have. Each stash entry is listed with its name (e.g. stash@{0}
is the latest entry, stash@{1}
is the one before, etc.), the name of the branch that was current when the entry was made, and a short description of the commit the entry was based on.
stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation
stash@{1}: On master: 9cc0589... Add git-stash
The command takes options applicable to the git log command to control what is shown and how. See git-log[1].
show [<options>] [<stash>]
Show the changes recorded in the stash entry as a diff between the stashed contents and the commit back when the stash entry was first created. When no <stash>
is given, it shows the latest one. By default, the command shows the diffstat, but it will accept any format known to git diff (e.g., git stash show -p stash@{1}
to view the second most recent entry in patch form). You can use stash.showStat and/or stash.showPatch config variables to change the default behavior.
pop [--index] [-q|--quiet] [<stash>]
从存储列表中删除单个存储状态,并将其应用于当前工作树状态的顶部,即执行git stash push
的逆操作。 工作目录必须与索引匹配。
应用状态可能会因冲突而失败; 在这种情况下,它不会从存储列表中删除。 您需要手动解决冲突,然后手动调用git stash drop。
如果使用 --index
选项,则不仅尝试恢复工作树的更改,还尝试恢复索引的更改。 但是,当有冲突时(这些冲突存储在索引中,因此你不再可以像以前一样应用更改),这可能会失败。
如果未给出<stash>,则假定为stash@{0},否则<stash>必须是stash@{<revision>}形式的引用。
apply [--index] [-q|--quiet] [<stash>]
类似于pop
,但是不从存储列表中删除状态。 与pop
不同,<stash>
可能是任何看起来像由stash push
或stash create
创建的提交。
branch <branchname> [<stash>]
Creates and checks out a new branch named <branchname>
starting from the commit at which the <stash>
was originally created, applies the changes recorded in <stash>
to the new working tree and index. If that succeeds, and <stash>
is a reference of the form stash@{<revision>}
, it then drops the <stash>
. When no <stash>
is given, applies the latest one.
This is useful if the branch on which you ran git stash push
has changed enough that git stash apply
fails due to conflicts. Since the stash entry is applied on top of the commit that was HEAD at the time git stash
was run, it restores the originally stashed state with no conflicts.
clear
Remove all the stash entries. Note that those entries will then be subject to pruning, and may be impossible to recover (see Examples below for a possible strategy).
drop [-q|--quiet] [<stash>]
Remove a single stash entry from the list of stash entries. When no <stash>
is given, it removes the latest one. i.e. stash@{0}
, otherwise <stash>
must be a valid stash log reference of the form stash@{<revision>}
.
create
Create a stash entry (which is a regular commit object) and return its object name, without storing it anywhere in the ref namespace. This is intended to be useful for scripts. It is probably not the command you want to use; see "push" above.
store
Store a given stash created via git stash create (which is a dangling merge commit) in the stash ref, updating the stash reflog. This is intended to be useful for scripts. It is probably not the command you want to use; see "push" above.
A stash entry is represented as a commit whose tree records the state of the working directory, and its first parent is the commit at HEAD
when the entry was created. The tree of the second parent records the state of the index when the entry is made, and it is made a child of the HEAD
commit.
一个存储条目表示为一个提交,这个提交的树记录了工作目录的状态,其第一个父级是创建条目时位于HEAD的提交。 第二个父级的树记录创建条目时的索引状态,并使其成为HEAD提交的子级。
The ancestry graph looks like this血统图如下所示:
.----W
/ /
-----H----I
where H
is the HEAD
commit, I
is a commit that records the state of the index, and W
is a commit that records the state of the working tree.
Pulling into a dirty tree
当你处于某种中间状态时,您会了解到上游的变化可能与您所做的事情有关。 当您的本地更改与上游更改不冲突时,简单的git pull将使您继续前进。
但是,在某些情况下,你本地更改与上游更改确实存在冲突,并且git pull拒绝覆盖你本地的更改。
在这种情况下,您可以将更改保存起来git stash,执行拉取git pull,然后取消保存 gitstash pop,如下所示:
$ git pull
...
file foobar not up to date, cannot merge.
$ git stash
$ git pull
$ git stash pop
Interrupted workflow
当你处于某种中间状态时,老板会进来并要求您立即修复某些问题。 传统上,您将做一个提交到临时分支以保存所做的更改,然后返回到原始分支以进行紧急修复,如下所示:
# ... 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 ...
Testing partial commits
当你想在工作树的更改中进行两次或更多次提交,并且想要在提交之前测试每个更改时,可以使用 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'
Recovering stash entries that were cleared/dropped erroneously
如果您错误地丢弃或清除存储条目,则无法通过常规安全机制对其进行恢复。 但是,您可以尝试以下命令以获取仍在存储库中但不再可访问的隐藏条目的列表:
git fsck --unreachable |
grep commit | cut -d\ -f3 |
xargs git log --merges --no-walk --grep=WIP