2 # Copyright (c) 2007, Nanako Shiraishi
4 dashless
=$
(basename "$0" |
sed -e 's/-/ /')
5 USAGE
="list [<options>]
6 or: $dashless show [<stash>]
7 or: $dashless drop [-q|--quiet] [<stash>]
8 or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]
9 or: $dashless branch <branchname> [<stash>]
10 or: $dashless [save [--patch] [-k|--[no-]keep-index] [-q|--quiet] [<message>]]
21 TMP
="$GIT_DIR/.git-stash.$$"
22 TMPindex
=${GIT_INDEX_FILE-"$GIT_DIR/index"}.stash.$$
23 trap 'rm -f "$TMP-"* "$TMPindex"' 0
27 if git config
--get-colorbool color.interactive
; then
28 help_color
="$(git config --get-color color.interactive.help 'red bold')"
29 reset_color
="$(git config --get-color '' reset)"
36 git diff-index
--quiet --cached HEAD
--ignore-submodules -- &&
37 git diff-files
--quiet --ignore-submodules
43 die
"$(gettext "git stash
clear with parameters is unimplemented
")"
45 if current
=$
(git rev-parse
--verify $ref_stash 2>/dev
/null
)
47 git update-ref
-d $ref_stash $current
54 git update-index
-q --refresh
60 # state of the base commit
61 if b_commit
=$
(git rev-parse
--verify HEAD
)
63 head=$
(git rev-list
--oneline -n 1 HEAD
--)
65 die
"$(gettext "You
do not have the initial commit yet
")"
68 if branch
=$
(git symbolic-ref
-q HEAD
)
70 branch
=${branch#refs/heads/}
74 msg
=$
(printf '%s: %s' "$branch" "$head")
77 i_tree
=$
(git write-tree
) &&
78 i_commit
=$
(printf 'index on %s\n' "$msg" |
79 git commit-tree
$i_tree -p $b_commit) ||
80 die
"$(gettext "Cannot save the current index state
")"
82 if test -z "$patch_mode"
85 # state of the working tree
87 git read-tree
--index-output="$TMPindex" -m $i_tree &&
88 GIT_INDEX_FILE
="$TMPindex" &&
89 export GIT_INDEX_FILE
&&
90 git
diff --name-only -z HEAD | git update-index
-z --add --remove --stdin &&
94 die
"$(gettext "Cannot save the current worktree state
")"
99 GIT_INDEX_FILE
="$TMP-index" git read-tree HEAD
&&
101 # find out what the user wants
102 GIT_INDEX_FILE
="$TMP-index" \
103 git add--interactive
--patch=stash
-- &&
105 # state of the working tree
106 w_tree
=$
(GIT_INDEX_FILE
="$TMP-index" git write-tree
) ||
107 die
"$(gettext "Cannot save the current worktree state
")"
109 git diff-tree
-p HEAD
$w_tree > "$TMP-patch" &&
110 test -s "$TMP-patch" ||
111 die
"$(gettext "No changes selected
")"
113 rm -f "$TMP-index" ||
114 die
"$(gettext "Cannot remove temporary index
(can
't happen)")"
119 if test -z "$stash_msg"
121 stash_msg=$(printf 'WIP on
%s
' "$msg")
123 stash_msg=$(printf 'On
%s
: %s
' "$branch" "$stash_msg")
125 w_commit=$(printf '%s
\n' "$stash_msg" |
126 git commit-tree $w_tree -p $b_commit -p $i_commit) ||
127 die "$(gettext "Cannot record working tree state")"
144 # only default to keep if we don't already have an override
145 test -z "$keep_index" && keep_index
=t
156 # TRANSLATORS: $option is an invalid option, like
157 # `--blah-blah'. The 7 spaces at the beginning of the
158 # second line correspond to "error: ". So you should line
159 # up the second line with however many characters the
160 # translation of "error: " takes in your language. E.g. in
163 # $ git stash save --blah-blah 2>&1 | head -n 2
164 # error: unknown option for 'stash save': --blah-blah
165 # To provide a message, use git stash save -- '--blah-blah'
166 eval_gettext
"$("error
: unknown option
for 'stash save': \
$option
167 To provide a message
, use git stash save
-- '\$option'")"; echo
179 git update-index
-q --refresh
182 say
"$(gettext "No
local changes to save
")"
185 test -f "$GIT_DIR/logs/$ref_stash" ||
186 clear_stash || die
"$(gettext "Cannot initialize stash
")"
188 create_stash
"$stash_msg"
190 # Make sure the reflog for stash is kept.
191 : >>"$GIT_DIR/logs/$ref_stash"
193 git update-ref
-m "$stash_msg" $ref_stash $w_commit ||
194 die
"$(gettext "Cannot save the current status
")"
195 say Saved working directory and index state
"$stash_msg"
197 if test -z "$patch_mode"
199 git
reset --hard ${GIT_QUIET:+-q}
201 if test "$keep_index" = "t" && test -n $i_tree
203 git read-tree
--reset -u $i_tree
206 git apply
-R < "$TMP-patch" ||
207 die
"$(gettext "Cannot remove worktree changes
")"
209 if test "$keep_index" != "t"
217 git rev-parse
--verify $ref_stash >/dev
/null
2>&1
221 have_stash ||
return 0
222 git log
--format="%gd: %gs" -g "$@" $ref_stash --
226 assert_stash_like
"$@"
228 git
diff ${FLAGS:---stat} $b_commit $w_commit
232 # Parses the remaining options looking for flags and
233 # at most one revision defaulting to ${ref_stash}@{0}
236 # Derives related tree and commit objects from the
237 # revision, if one is found.
239 # stash records the work tree, and is a merge between the
240 # base commit (first parent) and the index tree (second parent).
242 # REV is set to the symbolic version of the specified stash-like commit
243 # IS_STASH_LIKE is non-blank if ${REV} looks like a stash
244 # IS_STASH_REF is non-blank if the ${REV} looks like a stash ref
245 # s is set to the SHA1 of the stash commit
246 # w_commit is set to the commit containing the working tree
247 # b_commit is set to the base commit
248 # i_commit is set to the commit containing the index tree
249 # w_tree is set to the working tree
250 # b_tree is set to the base tree
251 # i_tree is set to the index tree
253 # GIT_QUIET is set to t if -q is specified
254 # INDEX_OPTION is set to --index if --index is specified.
255 # FLAGS is set to the remaining flags
258 # * too many revisions specified
259 # * no revision is specified and there is no stash stack
260 # * a revision is specified which cannot be resolve to a SHA1
261 # * a non-existent stash reference is specified
264 parse_flags_and_rev
()
266 test "$PARSE_CACHE" = "$*" && return 0 # optimisation
280 REV
=$
(git rev-parse
--no-flags --symbolic "$@") ||
exit 1
293 FLAGS
="${FLAGS}${FLAGS:+ }$opt"
302 have_stash || die
"$(gettext "No stash found.
")"
303 set -- ${ref_stash}@
{0}
309 die
"$(eval_gettext "Too many revisions specified
: \
$REV")"
313 REV
=$
(git rev-parse
--quiet --symbolic --verify $1 2>/dev
/null
) ||
{
315 die
"$(eval_gettext "\
$reference is not valid reference
")"
318 i_commit
=$
(git rev-parse
--quiet --verify $REV^
2 2>/dev
/null
) &&
319 set -- $
(git rev-parse
$REV $REV^
1 $REV: $REV^
1: $REV^
2: 2>/dev
/null
) &&
327 test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" &&
333 parse_flags_and_rev
"$@"
334 test -n "$IS_STASH_LIKE"
337 assert_stash_like
() {
338 is_stash_like
"$@" ||
{
340 die
"$(eval_gettext "'\$args' is not a stash-like commit
")"
345 is_stash_like
"$@" && test -n "$IS_STASH_REF"
349 is_stash_ref
"$@" ||
{
351 die
"$(eval_gettext "'\$args' is not a stash reference
")"
357 assert_stash_like
"$@"
359 git update-index
-q --refresh || die
"$(gettext "unable to refresh index
")"
361 # current index state
362 c_tree
=$
(git write-tree
) ||
363 die
"$(gettext "Cannot apply a stash
in the middle of a merge
")"
365 unstashed_index_tree
=
366 if test -n "$INDEX_OPTION" && test "$b_tree" != "$i_tree" &&
367 test "$c_tree" != "$i_tree"
369 git diff-tree
--binary $s^
2^..
$s^
2 | git apply
--cached
371 die
"$(gettext "Conflicts
in index. Try without
--index.
")"
372 unstashed_index_tree
=$
(git write-tree
) ||
373 die
"$(gettext "Could not save index tree
")"
378 GITHEAD_$w_tree='Stashed changes' &&
379 GITHEAD_$c_tree='Updated upstream' &&
380 GITHEAD_$b_tree='Version stash was based on' &&
381 export GITHEAD_$w_tree GITHEAD_$c_tree GITHEAD_$b_tree
384 if test -n "$GIT_QUIET"
386 GIT_MERGE_VERBOSITY
=0 && export GIT_MERGE_VERBOSITY
388 if git merge-recursive
$b_tree -- $c_tree $w_tree
391 if test -n "$unstashed_index_tree"
393 git read-tree
"$unstashed_index_tree"
396 git diff-index
--cached --name-only --diff-filter=A
$c_tree >"$a" &&
397 git read-tree
--reset $c_tree &&
398 git update-index
--add --stdin <"$a" ||
399 die
"$(gettext "Cannot unstage modified files
")"
403 if test -n "$GIT_QUIET"
405 squelch
='>/dev/null 2>&1'
407 (cd "$START_DIR" && eval "git status $squelch") ||
:
409 # Merge conflict; keep the exit status from merge-recursive
411 if test -n "$INDEX_OPTION"
414 gettext "Index was not unstashed." &&
423 assert_stash_ref
"$@"
430 assert_stash_ref
"$@"
432 git reflog delete
--updateref --rewrite "${REV}" &&
433 say
"$(eval_gettext "Dropped \
${REV} (\
$s)")" ||
434 die
"$(eval_gettext "\
${REV}: Could not drop stash entry
")"
436 # clear_stash if we just dropped the last stash entry
437 git rev-parse
--verify "$ref_stash@{0}" > /dev
/null
2>&1 || clear_stash
441 test -n "$1" || die
"$(gettext "No branch name specified
")"
446 assert_stash_like
"$@"
448 git checkout
-b $branch $REV^
&&
449 apply_stash
"$@" && {
450 test -z "$IS_STASH_REF" || drop_stash
"$@"
454 PARSE_CACHE
='--not-parsed'
455 # The default command is "save" if nothing but options are given
461 *) seen_non_option
=t
; break ;;
465 test -n "$seen_non_option" ||
set "save" "$@"
490 if test $# -gt 0 && test "$1" = create
494 create_stash
"$*" && echo "$w_commit"
512 say
"$(gettext "(To restore them
type \"git stash apply
\")")"