stash: introduce 'git stash store'
save_stash() contains the logic for doing two potentially independent operations; the first is preparing the stash merge commit, and the second is updating the stash ref/ reflog accordingly. While the first operation is abstracted out into a create_stash() for callers to access via 'git stash create', the second one is not. Fix this by factoring out the logic for storing the stash into a store_stash() that callers can access via 'git stash store'. Like create, store is not intended for end user interactive use, but for callers in other scripts. We can simplify the logic in the rebase.autostash feature using this new subcommand. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Ramkumar Ramachandra committed
Jun 15, 2013 at 18:43 UTC
bd514cada4bb1a396a58d408c3ec08526a8be742
3 files changed
+67
-6
Documentation/git-stash.txt
+7
@@ -17,6 +17,7 @@ SYNOPSIS
17
[-u|--include-untracked] [-a|--all] [<message>]]
18
'git stash' clear
19
'git stash' create [<message>]
20
+'git stash' store [-m|--message <message>] [-q|--quiet] <commit>
21
22
DESCRIPTION
23
-----------
@@ -154,6 +155,12 @@ create::
155
This is intended to be useful for scripts. It is probably not
156
the command you want to use; see "save" above.
157
158
+store::
159
+
160
+ Store a given stash created via 'git stash create' (which is a
161
+ dangling merge commit) in the stash ref, updating the stash
162
+ reflog. This is intended to be useful for scripts. It is
163
+ probably not the command you want to use; see "save" above.
164
165
DISCUSSION
166
----------
git-stash.sh
+41
-6
@@ -156,6 +156,41 @@ create_stash () {
156
die "$(gettext "Cannot record working tree state")"
157
}
158
159
+store_stash () {
160
+ while test $# != 0
161
+ do
162
+ case "$1" in
163
+ -m|--message)
164
+ shift
165
+ stash_msg="$1"
166
+ ;;
167
+ -q|--quiet)
168
+ quiet=t
169
+ ;;
170
+ *)
171
+ break
172
+ ;;
173
+ esac
174
+ shift
175
+ done
176
+ test $# = 1 ||
177
+ die "$(eval_gettext "\"$dashless store\" requires one <commit> argument")"
178
+
179
+ w_commit="$1"
180
+ if test -z "$stash_msg"
181
+ then
182
+ stash_msg="Created via \"git stash store\"."
183
+ fi
184
+
185
+ # Make sure the reflog for stash is kept.
186
+ : >>"$GIT_DIR/logs/$ref_stash"
187
+ git update-ref -m "$stash_msg" $ref_stash $w_commit
188
+ ret=$?
189
+ test $ret != 0 && test -z $quiet &&
190
+ die "$(eval_gettext "Cannot update \$ref_stash with \$w_commit")"
191
+ return $ret
192
+}
193
+
194
save_stash () {
195
keep_index=
196
patch_mode=
@@ -227,12 +262,8 @@ save_stash () {
262
clear_stash || die "$(gettext "Cannot initialize stash")"
263
264
create_stash "$stash_msg" $untracked
230
-
231
- # Make sure the reflog for stash is kept.
232
- : >>"$GIT_DIR/logs/$ref_stash"
233
-
234
- git update-ref -m "$stash_msg" $ref_stash $w_commit ||
235
- die "$(gettext "Cannot save the current status")"
265
+ store_stash -m "$stash_msg" -q $w_commit ||
266
+ die "$(gettext "Cannot save the current status")"
267
say Saved working directory and index state "$stash_msg"
268
269
if test -z "$patch_mode"
@@ -549,6 +580,10 @@ create)
580
shift
581
create_stash "$*" && echo "$w_commit"
582
;;
583
+store)
584
+ shift
585
+ store_stash "$@"
586
+ ;;
587
drop)
588
shift
589
drop_stash "$@"
t/t3903-stash.sh
+19
@@ -637,4 +637,23 @@ test_expect_success 'stash where working directory contains "HEAD" file' '
637
test_cmp output expect
638
'
639
640
+test_expect_success 'store called with invalid commit' '
641
+ test_must_fail git stash store foo
642
+'
643
+
644
+test_expect_success 'store updates stash ref and reflog' '
645
+ git stash clear &&
646
+ git reset --hard &&
647
+ echo quux >bazzy &&
648
+ git add bazzy &&
649
+ STASH_ID=$(git stash create) &&
650
+ git reset --hard &&
651
+ ! grep quux bazzy &&
652
+ git stash store -m quuxery $STASH_ID &&
653
+ test $(cat .git/refs/stash) = $STASH_ID &&
654
+ grep $STASH_ID .git/logs/refs/stash &&
655
+ git stash pop &&
656
+ grep quux bazzy
657
+'
658
+
659
test_done