Skip to content

Commit

Permalink
rebase: add --quit to cleanup rebase, leave everything else untouched
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
pclouds authored and gitster committed Dec 11, 2016
1 parent 0b65a8d commit 9512177
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 4 deletions.
7 changes: 6 additions & 1 deletion Documentation/git-rebase.txt
Expand Up @@ -12,7 +12,7 @@ SYNOPSIS
[<upstream> [<branch>]]
'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
--root [<branch>]
'git rebase' --continue | --skip | --abort | --edit-todo
'git rebase' --continue | --skip | --abort | --quit | --edit-todo

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

--quit::
Abort the rebase operation but HEAD is not reset back to the
original branch. The index and working tree are also left
unchanged as a result.

--keep-empty::
Keep the commits that do not change anything from its
parents in the result.
Expand Down
4 changes: 2 additions & 2 deletions contrib/completion/git-completion.bash
Expand Up @@ -1670,10 +1670,10 @@ _git_rebase ()
{
local dir="$(__gitdir)"
if [ -f "$dir"/rebase-merge/interactive ]; then
__gitcomp "--continue --skip --abort --edit-todo"
__gitcomp "--continue --skip --abort --quit --edit-todo"
return
elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
__gitcomp "--continue --skip --abort"
__gitcomp "--continue --skip --abort --quit"
return
fi
__git_complete_strategy && return
Expand Down
6 changes: 5 additions & 1 deletion git-rebase.sh
Expand Up @@ -43,6 +43,7 @@ continue! continue
abort! abort and check out the original branch
skip! skip current patch and continue
edit-todo! edit the todo list during an interactive rebase
quit! abort but keep HEAD where it is
"
. git-sh-setup
. git-sh-i18n
Expand Down Expand Up @@ -239,7 +240,7 @@ do
--verify)
ok_to_skip_pre_rebase=
;;
--continue|--skip|--abort|--edit-todo)
--continue|--skip|--abort|--quit|--edit-todo)
test $total_argc -eq 2 || usage
action=${1##--}
;;
Expand Down Expand Up @@ -402,6 +403,9 @@ abort)
finish_rebase
exit
;;
quit)
exec rm -rf "$state_dir"
;;
edit-todo)
run_specific_rebase
;;
Expand Down
24 changes: 24 additions & 0 deletions t/t3407-rebase-abort.sh
Expand Up @@ -99,4 +99,28 @@ testrebase() {
testrebase "" .git/rebase-apply
testrebase " --merge" .git/rebase-merge

test_expect_success 'rebase --quit' '
cd "$work_dir" &&
# Clean up the state from the previous one
git reset --hard pre-rebase &&
test_must_fail git rebase master &&
test_path_is_dir .git/rebase-apply &&
head_before=$(git rev-parse HEAD) &&
git rebase --quit &&
test $(git rev-parse HEAD) = $head_before &&
test ! -d .git/rebase-apply
'

test_expect_success 'rebase --merge --quit' '
cd "$work_dir" &&
# Clean up the state from the previous one
git reset --hard pre-rebase &&
test_must_fail git rebase --merge master &&
test_path_is_dir .git/rebase-merge &&
head_before=$(git rev-parse HEAD) &&
git rebase --quit &&
test $(git rev-parse HEAD) = $head_before &&
test ! -d .git/rebase-merge
'

test_done

0 comments on commit 9512177

Please sign in to comment.