Skip to content

Commit 9512177

Browse files
pcloudsgitster
authored andcommitted
rebase: add --quit to cleanup rebase, leave everything else untouched
There are occasions when you decide to abort an in-progress rebase and move on to do something else but you forget to do "git rebase --abort" first. Or the rebase has been in progress for so long you forgot about it. By the time you realize that (e.g. by starting another rebase) it's already too late to retrace your steps. The solution is normally rm -r .git/<some rebase dir> and continue with your life. But there could be two different directories for <some rebase dir> (and it obviously requires some knowledge of how rebase works), and the ".git" part could be much longer if you are not at top-dir, or in a linked worktree. And "rm -r" is very dangerous to do in .git, a mistake in there could destroy object database or other important data. Provide "git rebase --quit" for this use case, mimicking a precedent that is "git cherry-pick --quit". Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 0b65a8d commit 9512177

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

Documentation/git-rebase.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ SYNOPSIS
1212
[<upstream> [<branch>]]
1313
'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
1414
--root [<branch>]
15-
'git rebase' --continue | --skip | --abort | --edit-todo
15+
'git rebase' --continue | --skip | --abort | --quit | --edit-todo
1616

1717
DESCRIPTION
1818
-----------
@@ -252,6 +252,11 @@ leave out at most one of A and B, in which case it defaults to HEAD.
252252
will be reset to where it was when the rebase operation was
253253
started.
254254

255+
--quit::
256+
Abort the rebase operation but HEAD is not reset back to the
257+
original branch. The index and working tree are also left
258+
unchanged as a result.
259+
255260
--keep-empty::
256261
Keep the commits that do not change anything from its
257262
parents in the result.

contrib/completion/git-completion.bash

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,10 +1670,10 @@ _git_rebase ()
16701670
{
16711671
local dir="$(__gitdir)"
16721672
if [ -f "$dir"/rebase-merge/interactive ]; then
1673-
__gitcomp "--continue --skip --abort --edit-todo"
1673+
__gitcomp "--continue --skip --abort --quit --edit-todo"
16741674
return
16751675
elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1676-
__gitcomp "--continue --skip --abort"
1676+
__gitcomp "--continue --skip --abort --quit"
16771677
return
16781678
fi
16791679
__git_complete_strategy && return

git-rebase.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ continue! continue
4343
abort! abort and check out the original branch
4444
skip! skip current patch and continue
4545
edit-todo! edit the todo list during an interactive rebase
46+
quit! abort but keep HEAD where it is
4647
"
4748
. git-sh-setup
4849
. git-sh-i18n
@@ -239,7 +240,7 @@ do
239240
--verify)
240241
ok_to_skip_pre_rebase=
241242
;;
242-
--continue|--skip|--abort|--edit-todo)
243+
--continue|--skip|--abort|--quit|--edit-todo)
243244
test $total_argc -eq 2 || usage
244245
action=${1##--}
245246
;;
@@ -402,6 +403,9 @@ abort)
402403
finish_rebase
403404
exit
404405
;;
406+
quit)
407+
exec rm -rf "$state_dir"
408+
;;
405409
edit-todo)
406410
run_specific_rebase
407411
;;

t/t3407-rebase-abort.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,28 @@ testrebase() {
9999
testrebase "" .git/rebase-apply
100100
testrebase " --merge" .git/rebase-merge
101101

102+
test_expect_success 'rebase --quit' '
103+
cd "$work_dir" &&
104+
# Clean up the state from the previous one
105+
git reset --hard pre-rebase &&
106+
test_must_fail git rebase master &&
107+
test_path_is_dir .git/rebase-apply &&
108+
head_before=$(git rev-parse HEAD) &&
109+
git rebase --quit &&
110+
test $(git rev-parse HEAD) = $head_before &&
111+
test ! -d .git/rebase-apply
112+
'
113+
114+
test_expect_success 'rebase --merge --quit' '
115+
cd "$work_dir" &&
116+
# Clean up the state from the previous one
117+
git reset --hard pre-rebase &&
118+
test_must_fail git rebase --merge master &&
119+
test_path_is_dir .git/rebase-merge &&
120+
head_before=$(git rev-parse HEAD) &&
121+
git rebase --quit &&
122+
test $(git rev-parse HEAD) = $head_before &&
123+
test ! -d .git/rebase-merge
124+
'
125+
102126
test_done

0 commit comments

Comments
 (0)