SYNOPSIS
--------
[verse]
- 'git stash' (list | show [<stash>] | apply [<stash>] | clear | drop [<stash>] | pop [<stash>])
+ 'git stash' list
+ 'git stash' (show | apply | drop | pop ) [<stash>]
+ 'git stash' branch <branchname> [<stash>]
'git stash' [save [<message>]]
+ 'git stash' clear
DESCRIPTION
-----------
OPTIONS
-------
-save [<message>]::
+save [--keep-index] [<message>]::
Save your local modifications to a new 'stash', and run `git reset
--hard` to revert them. This is the default action when no
subcommand is given. The <message> part is optional and gives
the description along with the stashed state.
++
+If the `--keep-index` option is used, all changes already added to the
+index are left intact.
list [<options>]::
stash@{1}: On master: 9cc0589... Add git-stash
----------------------------------------------------------------
+
-The command takes options applicable to the `git-log`
+The command takes options applicable to the 'git-log'
command to control what is shown and how. See linkgit:git-log[1].
show [<stash>]::
Show the changes recorded in the stash as a diff between the
stashed state and its original parent. When no `<stash>` is given,
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
+ it will accept any format known to 'git-diff' (e.g., `git stash show
-p stash@\{1}` to view the second most recent stash in patch form).
apply [--index] [<stash>]::
have conflicts (which are stored in the index, where you therefore can no
longer apply the changes as they were originally).
+ 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, then
+ drops the `<stash>` if that completes successfully. When no `<stash>`
+ is given, applies the latest one.
+ +
+ This is useful if the branch on which you ran `git stash save` has
+ changed enough that `git stash apply` fails due to conflicts. Since
+ the stash 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 stashed states. Note that those states will then
be subject to pruning, and may be difficult or impossible to recover.
... continue hacking ...
----------------------------------------------------------------
+
-You can use `git-stash` to simplify the above, like this:
+You can use 'git-stash' to simplify the above, like this:
+
----------------------------------------------------------------
... hack hack hack ...
... continue hacking ...
----------------------------------------------------------------
+Testing partial commits::
+
+You can use `git stash save --keep-index` when you want to make two or
+more commits out of the changes in the work tree, and you want to test
+each change before committing:
++
+----------------------------------------------------------------
+... 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 foo -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'
+----------------------------------------------------------------
+
SEE ALSO
--------
linkgit:git-checkout[1],
}
save_stash () {
+ keep_index=
+ case "$1" in
+ --keep-index)
+ keep_index=t
+ shift
+ esac
+
stash_msg="$1"
if no_changes
git update-ref -m "$stash_msg" $ref_stash $w_commit ||
die "Cannot save the current status"
printf 'Saved working directory and index state "%s"\n' "$stash_msg"
+
+ git reset --hard
+
+ if test -n "$keep_index" && test -n $i_tree
+ then
+ git read-tree --reset -u $i_tree
+ fi
}
have_stash () {
die "$*: no valid stashed state found"
unstashed_index_tree=
- if test -n "$unstash_index" && test "$b_tree" != "$i_tree"
+ if test -n "$unstash_index" && test "$b_tree" != "$i_tree" &&
+ test "$c_tree" != "$i_tree"
then
git diff-tree --binary $s^2^..$s^2 | git apply --cached
test $? -ne 0 &&
git rev-parse --verify "$ref_stash@{0}" > /dev/null 2>&1 || clear_stash
}
+ apply_to_branch () {
+ have_stash || die 'Nothing to apply'
+
+ test -n "$1" || die 'No branch name specified'
+ branch=$1
+
+ if test -z "$2"
+ then
+ set x "$ref_stash@{0}"
+ fi
+ stash=$2
+
+ git-checkout -b $branch $stash^ &&
+ apply_stash --index $stash &&
+ drop_stash $stash
+ }
+
# Main command set
case "$1" in
list)
;;
save)
shift
- save_stash "$*" && git-reset --hard
+ save_stash "$*"
;;
apply)
shift
drop_stash "$@"
fi
;;
+ branch)
+ shift
+ apply_to_branch "$@"
+ ;;
*)
if test $# -eq 0
then
save_stash &&
- echo '(To restore them type "git stash apply")' &&
- git-reset --hard
+ echo '(To restore them type "git stash apply")'
else
usage
fi