Skip to content

Commit 6c9ad16

Browse files
committed
rebase: allow starting from a dirty tree.
This uses the new "git stash create" interface to stash away the dirty state you have in your working tree before starting a rebase, and then replaying it when you are done with stashing. Signed-off-by: Junio C Hamano <[email protected]>
1 parent bc9e739 commit 6c9ad16

File tree

1 file changed

+58
-14
lines changed

1 file changed

+58
-14
lines changed

git-rebase.sh

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,30 @@ call_merge () {
116116
}
117117

118118
finish_rb_merge () {
119+
if test -f "$dotest/stash"
120+
then
121+
stash=$(cat "$dotest/stash")
122+
git stash apply --index "$stash"
123+
fi
119124
rm -r "$dotest"
120125
echo "All done."
121126
}
122127

128+
read_stash () {
129+
if test -f "$1"
130+
then
131+
cat "$1"
132+
fi
133+
}
134+
unstash_and_exit () {
135+
err=$?
136+
if test -f "$1" && test $err = 0
137+
then
138+
git stash apply --index "$1"
139+
fi
140+
exit $err
141+
}
142+
123143
is_interactive () {
124144
test -f "$dotest"/interactive ||
125145
while case $#,"$1" in 0,|*,-i|*,--interactive) break ;; esac
@@ -154,8 +174,9 @@ do
154174
finish_rb_merge
155175
exit
156176
fi
177+
stash=$(read_stash ".dotest/stash")
157178
git am --resolved --3way --resolvemsg="$RESOLVEMSG"
158-
exit
179+
unstash_and_exit "$stash"
159180
;;
160181
--skip)
161182
if test -d "$dotest"
@@ -174,21 +195,31 @@ do
174195
finish_rb_merge
175196
exit
176197
fi
198+
stash=$(read_stash ".dotest/stash")
177199
git am -3 --skip --resolvemsg="$RESOLVEMSG"
178-
exit
200+
unstash_and_exit "$stash"
179201
;;
180202
--abort)
181203
git rerere clear
182204
if test -d "$dotest"
183205
then
206+
if test -f "$dotest/stash"
207+
then
208+
stash=$(cat "$dotest/stash")
209+
fi
184210
rm -r "$dotest"
185211
elif test -d .dotest
186212
then
213+
if test -f ".dotest/stash"
214+
then
215+
stash=$(cat ".dotest/stash")
216+
fi
187217
rm -r .dotest
188218
else
189219
die "No rebase in progress?"
190220
fi
191221
git reset --hard ORIG_HEAD
222+
test -z "$stash" || git stash apply --index "$stash"
192223
exit
193224
;;
194225
--onto)
@@ -254,16 +285,6 @@ else
254285
fi
255286
fi
256287

257-
# The tree must be really really clean.
258-
git update-index --refresh || exit
259-
diff=$(git diff-index --cached --name-status -r HEAD)
260-
case "$diff" in
261-
?*) echo "cannot rebase: your index is not up-to-date"
262-
echo "$diff"
263-
exit 1
264-
;;
265-
esac
266-
267288
# The upstream head must be given. Make sure it is valid.
268289
upstream_name="$1"
269290
upstream=`git rev-parse --verify "${upstream_name}^0"` ||
@@ -273,11 +294,19 @@ upstream=`git rev-parse --verify "${upstream_name}^0"` ||
273294
onto_name=${newbase-"$upstream_name"}
274295
onto=$(git rev-parse --verify "${onto_name}^0") || exit
275296

297+
# The tree must be clean enough for us to create a stash
298+
stash=$(git stash create) || exit
299+
if test -n "$stash"
300+
then
301+
echo >&2 "Stashed away your working tree changes"
302+
fi
303+
276304
# If a hook exists, give it a chance to interrupt
277305
if test -x "$GIT_DIR/hooks/pre-rebase"
278306
then
279307
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
280308
echo >&2 "The pre-rebase hook refused to rebase."
309+
test -z "$stash" || git stash apply --index "$stash"
281310
exit 1
282311
}
283312
fi
@@ -286,7 +315,10 @@ fi
286315
case "$#" in
287316
2)
288317
branch_name="$2"
289-
git-checkout "$2" || usage
318+
git-checkout "$2" || {
319+
test -z "$stash" || git stash apply --index "$stash"
320+
usage
321+
}
290322
;;
291323
*)
292324
if branch_name=`git symbolic-ref -q HEAD`
@@ -309,6 +341,7 @@ if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
309341
! git rev-list --parents "$onto".."$branch" | grep " .* " > /dev/null
310342
then
311343
echo >&2 "Current branch $branch_name is up to date."
344+
test -z "$stash" || git stash apply --index "$stash"
312345
exit 0
313346
fi
314347

@@ -328,14 +361,24 @@ git-reset --hard "$onto"
328361
if test "$mb" = "$branch"
329362
then
330363
echo >&2 "Fast-forwarded $branch_name to $onto_name."
364+
test -z "$stash" || git stash apply --index "$stash"
331365
exit 0
332366
fi
333367

334368
if test -z "$do_merge"
335369
then
336370
git format-patch -k --stdout --full-index --ignore-if-in-upstream "$upstream"..ORIG_HEAD |
337371
git am $git_am_opt --binary -3 -k --resolvemsg="$RESOLVEMSG"
338-
exit $?
372+
err=$?
373+
374+
if test $err = 0
375+
then
376+
test -z "$stash" || git stash apply --index "$stash"
377+
exit
378+
else
379+
test -z "$stash" || echo "$stash" >.dotest/stash
380+
exit $err
381+
fi
339382
fi
340383

341384
# start doing a rebase with git-merge
@@ -346,6 +389,7 @@ echo "$onto" > "$dotest/onto"
346389
echo "$onto_name" > "$dotest/onto_name"
347390
prev_head=`git rev-parse HEAD^0`
348391
echo "$prev_head" > "$dotest/prev_head"
392+
test -z "$stash" || echo "$stash" >"$dotest/stash"
349393

350394
msgnum=0
351395
for cmt in `git rev-list --reverse --no-merges "$upstream"..ORIG_HEAD`

0 commit comments

Comments
 (0)