rebase: on abort delete rebase state file no matter what
authorChristian Delahousse <cdelahousse@fb.com>
Thu, 15 Oct 2015 12:13:46 -0700
changeset 26744 21e50e36de02
parent 26743 58b04a538caa
child 26745 8af610bce239
rebase: on abort delete rebase state file no matter what When a user's repository is in an unfinished rebase state and they choose to abort, at a minimum, the repo should be out of that state. We've found situations where the user could not leave the state unless manually deleting the rebasestate file. This fix ensures that no matter what exception may be raised during the abort, the rebase state file will be deleted, the user will be out of the rebase state and they can get their repository into a workable condition.
hgext/rebase.py
--- a/hgext/rebase.py	Fri Oct 16 15:01:42 2015 -0700
+++ b/hgext/rebase.py	Thu Oct 15 12:13:46 2015 -0700
@@ -926,43 +926,46 @@
     activebookmark: the name of the bookmark that should be active after the
         restore'''
 
-    # If the first commits in the rebased set get skipped during the rebase,
-    # their values within the state mapping will be the target rev id. The
-    # dstates list must must not contain the target rev (issue4896)
-    dstates = [s for s in state.values() if s >= 0 and s != target]
-    immutable = [d for d in dstates if not repo[d].mutable()]
-    cleanup = True
-    if immutable:
-        repo.ui.warn(_("warning: can't clean up public changesets %s\n")
-                     % ', '.join(str(repo[r]) for r in immutable),
-                     hint=_('see "hg help phases" for details'))
-        cleanup = False
+    try:
+        # If the first commits in the rebased set get skipped during the rebase,
+        # their values within the state mapping will be the target rev id. The
+        # dstates list must must not contain the target rev (issue4896)
+        dstates = [s for s in state.values() if s >= 0 and s != target]
+        immutable = [d for d in dstates if not repo[d].mutable()]
+        cleanup = True
+        if immutable:
+            repo.ui.warn(_("warning: can't clean up public changesets %s\n")
+                        % ', '.join(str(repo[r]) for r in immutable),
+                        hint=_('see "hg help phases" for details'))
+            cleanup = False
 
-    descendants = set()
-    if dstates:
-        descendants = set(repo.changelog.descendants(dstates))
-    if descendants - set(dstates):
-        repo.ui.warn(_("warning: new changesets detected on target branch, "
-                       "can't strip\n"))
-        cleanup = False
+        descendants = set()
+        if dstates:
+            descendants = set(repo.changelog.descendants(dstates))
+        if descendants - set(dstates):
+            repo.ui.warn(_("warning: new changesets detected on target branch, "
+                        "can't strip\n"))
+            cleanup = False
 
-    if cleanup:
-        # Update away from the rebase if necessary
-        if needupdate(repo, state):
-            merge.update(repo, originalwd, False, True, False)
+        if cleanup:
+            # Update away from the rebase if necessary
+            if needupdate(repo, state):
+                merge.update(repo, originalwd, False, True, False)
 
-        # Strip from the first rebased revision
-        rebased = filter(lambda x: x >= 0 and x != target, state.values())
-        if rebased:
-            strippoints = [c.node()  for c in repo.set('roots(%ld)', rebased)]
-            # no backup of rebased cset versions needed
-            repair.strip(repo.ui, repo, strippoints)
+            # Strip from the first rebased revision
+            rebased = filter(lambda x: x >= 0 and x != target, state.values())
+            if rebased:
+                strippoints = [
+                        c.node()  for c in repo.set('roots(%ld)', rebased)]
+                # no backup of rebased cset versions needed
+                repair.strip(repo.ui, repo, strippoints)
 
-    if activebookmark and activebookmark in repo._bookmarks:
-        bookmarks.activate(repo, activebookmark)
+        if activebookmark and activebookmark in repo._bookmarks:
+            bookmarks.activate(repo, activebookmark)
 
-    clearstatus(repo)
-    repo.ui.warn(_('rebase aborted\n'))
+    finally:
+        clearstatus(repo)
+        repo.ui.warn(_('rebase aborted\n'))
     return 0
 
 def buildstate(repo, dest, rebaseset, collapse, obsoletenotrebased):