histedit: extract InterventionRequired transaction handling to utils
authorMartin von Zweigbergk <martinvonz@google.com>
Wed, 12 Jul 2017 13:57:03 -0700
changeset 33446 fad6852cf879
parent 33445 0491004e2233
child 33447 6f4e5e5940a5
histedit: extract InterventionRequired transaction handling to utils rebase will have similar logic, so let's extract it. Besides, it makes the histedit code more readable. We may want to parametrize acceptintervention() by the exception(s) that should result in transaction close. Differential Revision: https://phab.mercurial-scm.org/D66
hgext/histedit.py
mercurial/util.py
--- a/hgext/histedit.py	Wed Jul 12 13:17:49 2017 -0700
+++ b/hgext/histedit.py	Wed Jul 12 13:57:03 2017 -0700
@@ -1122,7 +1122,7 @@
         # and reopen a transaction. For example, if the action executes an
         # external process it may choose to commit the transaction first.
         tr = repo.transaction('histedit')
-    try:
+    with util.acceptintervention(tr):
         while state.actions:
             state.write(tr=tr)
             actobj = state.actions[0]
@@ -1136,17 +1136,6 @@
             state.replacements.extend(replacement_)
             state.actions.pop(0)
 
-        if tr is not None:
-            tr.close()
-    except error.InterventionRequired:
-        if tr is not None:
-            tr.close()
-        raise
-    except Exception:
-        if tr is not None:
-            tr.abort()
-        raise
-
     state.write()
     ui.progress(_("editing"), None)
 
--- a/mercurial/util.py	Wed Jul 12 13:17:49 2017 -0700
+++ b/mercurial/util.py	Wed Jul 12 13:57:03 2017 -0700
@@ -19,6 +19,7 @@
 import calendar
 import codecs
 import collections
+import contextlib
 import datetime
 import errno
 import gc
@@ -589,6 +590,24 @@
             del self[key]
         super(sortdict, self).__setitem__(key, value)
 
+@contextlib.contextmanager
+def acceptintervention(tr=None):
+    """A context manager that closes the transaction on InterventionRequired
+
+    If no transaction was provided, this simply runs the body and returns
+    """
+    if not tr:
+        yield
+        return
+    try:
+        yield
+        tr.close()
+    except error.InterventionRequired:
+        tr.close()
+        raise
+    finally:
+        tr.release()
+
 class _lrucachenode(object):
     """A node in a doubly linked list.