diff mbox series

rebase: move state_dir to tmp prior to deletion

Message ID 01020168891b1a3e-140bd175-a8cb-4379-a114-de68b1cac5d6-000000@eu-west-1.amazonses.com (mailing list archive)
State New, archived
Headers show
Series rebase: move state_dir to tmp prior to deletion | expand

Commit Message

Ben Woosley Jan. 26, 2019, 7:41 a.m. UTC
From: Ben Woosley <ben.woosley@gmail.com>

To avoid partial deletion / zombie rebases.

Example behavior under partial deletion, after
Ctrl-Cing out of a standard rebase:

    $ git rebase target
    First, rewinding head to replay your work on top of it...
    Applying: [...]
    ^C
    $ git status
    rebase in progress; onto (null)
    You are currently rebasing.
      (all conflicts fixed: run "git rebase --continue")

    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    [...]
    $ git rebase --continue
    error: could not read '.git/rebase-apply/head-name': No such file or directory
    $ git rebase --abort
    error: could not read '.git/rebase-apply/head-name': No such file or directory

Others report this issue here:
https://stackoverflow.com/questions/3685001/git-how-to-fix-corrupted-interactive-rebase
---
 git-legacy-rebase.sh           | 17 ++++++++++++++---
 git-rebase--preserve-merges.sh |  2 +-
 2 files changed, 15 insertions(+), 4 deletions(-)


--
https://github.com/git/git/pull/569
diff mbox series

Patch

diff --git a/git-legacy-rebase.sh b/git-legacy-rebase.sh
index b4c7dbfa575d3..878c0e42054d7 100755
--- a/git-legacy-rebase.sh
+++ b/git-legacy-rebase.sh
@@ -128,11 +128,22 @@  read_basic_state () {
 	}
 }
 
+remove_rebase_state () {
+  state_tmpdir=$(mktemp -d -t "git-rebase-state-XXXXXX")
+  if test -d state_tmpdir
+  then
+    exec mv "$state_dir" "$state_tmpdir"
+    exec rm -rf "$state_tmpdir"
+  else
+    exec rm -rf "$state_dir"
+  fi
+}
+
 finish_rebase () {
 	rm -f "$(git rev-parse --git-path REBASE_HEAD)"
 	apply_autostash &&
 	{ git gc --auto || true; } &&
-	rm -rf "$state_dir"
+	remove_rebase_state
 }
 
 run_interactive () {
@@ -194,7 +205,7 @@  run_specific_rebase () {
 	elif test $ret -eq 2 # special exit status for rebase -p
 	then
 		apply_autostash &&
-		rm -rf "$state_dir" &&
+		remove_rebase_state &&
 		die "Nothing to do"
 	fi
 	exit $ret
@@ -439,7 +450,7 @@  abort)
 	exit
 	;;
 quit)
-	exec rm -rf "$state_dir"
+	remove_rebase_state
 	;;
 edit-todo)
 	run_specific_rebase
diff --git a/git-rebase--preserve-merges.sh b/git-rebase--preserve-merges.sh
index afbb65765d461..146b52df14928 100644
--- a/git-rebase--preserve-merges.sh
+++ b/git-rebase--preserve-merges.sh
@@ -226,7 +226,7 @@  Once you are satisfied with your changes, run
 
 die_abort () {
 	apply_autostash
-	rm -rf "$state_dir"
+	remove_rebase_state
 	die "$1"
 }