Skip to content

Commit 671d322

Browse files
committed
Merge branch 'am/stash-branch'
* am/stash-branch: Add a test for "git stash branch" Implement "git stash branch <newbranch> <stash>"
2 parents 15fc1c0 + 4a58807 commit 671d322

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

Documentation/git-stash.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ git-stash - Stash the changes in a dirty working directory away
88
SYNOPSIS
99
--------
1010
[verse]
11-
'git stash' (list | show [<stash>] | apply [<stash>] | clear | drop [<stash>] | pop [<stash>])
11+
'git stash' list
12+
'git stash' (show | apply | drop | pop ) [<stash>]
13+
'git stash' branch <branchname> [<stash>]
1214
'git stash' [save [<message>]]
15+
'git stash' clear
1316

1417
DESCRIPTION
1518
-----------
@@ -84,6 +87,20 @@ tree's changes, but also the index's ones. However, this can fail, when you
8487
have conflicts (which are stored in the index, where you therefore can no
8588
longer apply the changes as they were originally).
8689

90+
branch <branchname> [<stash>]::
91+
92+
Creates and checks out a new branch named `<branchname>` starting from
93+
the commit at which the `<stash>` was originally created, applies the
94+
changes recorded in `<stash>` to the new working tree and index, then
95+
drops the `<stash>` if that completes successfully. When no `<stash>`
96+
is given, applies the latest one.
97+
+
98+
This is useful if the branch on which you ran `git stash save` has
99+
changed enough that `git stash apply` fails due to conflicts. Since
100+
the stash is applied on top of the commit that was HEAD at the time
101+
`git stash` was run, it restores the originally stashed state with
102+
no conflicts.
103+
87104
clear::
88105
Remove all the stashed states. Note that those states will then
89106
be subject to pruning, and may be difficult or impossible to recover.

git-stash.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,23 @@ drop_stash () {
233233
git rev-parse --verify "$ref_stash@{0}" > /dev/null 2>&1 || clear_stash
234234
}
235235

236+
apply_to_branch () {
237+
have_stash || die 'Nothing to apply'
238+
239+
test -n "$1" || die 'No branch name specified'
240+
branch=$1
241+
242+
if test -z "$2"
243+
then
244+
set x "$ref_stash@{0}"
245+
fi
246+
stash=$2
247+
248+
git-checkout -b $branch $stash^ &&
249+
apply_stash --index $stash &&
250+
drop_stash $stash
251+
}
252+
236253
# Main command set
237254
case "$1" in
238255
list)
@@ -279,6 +296,10 @@ pop)
279296
drop_stash "$@"
280297
fi
281298
;;
299+
branch)
300+
shift
301+
apply_to_branch "$@"
302+
;;
282303
*)
283304
if test $# -eq 0
284305
then

t/t3903-stash.sh

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,64 @@ test_expect_success 'stash pop' '
117117
test 0 = $(git stash list | wc -l)
118118
'
119119

120+
cat > expect << EOF
121+
diff --git a/file2 b/file2
122+
new file mode 100644
123+
index 0000000..1fe912c
124+
--- /dev/null
125+
+++ b/file2
126+
@@ -0,0 +1 @@
127+
+bar2
128+
EOF
129+
130+
cat > expect1 << EOF
131+
diff --git a/file b/file
132+
index 257cc56..5716ca5 100644
133+
--- a/file
134+
+++ b/file
135+
@@ -1 +1 @@
136+
-foo
137+
+bar
138+
EOF
139+
140+
cat > expect2 << EOF
141+
diff --git a/file b/file
142+
index 7601807..5716ca5 100644
143+
--- a/file
144+
+++ b/file
145+
@@ -1 +1 @@
146+
-baz
147+
+bar
148+
diff --git a/file2 b/file2
149+
new file mode 100644
150+
index 0000000..1fe912c
151+
--- /dev/null
152+
+++ b/file2
153+
@@ -0,0 +1 @@
154+
+bar2
155+
EOF
156+
157+
test_expect_success 'stash branch' '
158+
echo foo > file &&
159+
git commit file -m first
160+
echo bar > file &&
161+
echo bar2 > file2 &&
162+
git add file2 &&
163+
git stash &&
164+
echo baz > file &&
165+
git commit file -m second &&
166+
git stash branch stashbranch &&
167+
test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
168+
test $(git rev-parse HEAD) = $(git rev-parse master^) &&
169+
git diff --cached > output &&
170+
test_cmp output expect &&
171+
git diff > output &&
172+
test_cmp output expect1 &&
173+
git add file &&
174+
git commit -m alternate\ second &&
175+
git diff master..stashbranch > output &&
176+
test_cmp output expect2 &&
177+
test 0 = $(git stash list | wc -l)
178+
'
179+
120180
test_done

0 commit comments

Comments
 (0)