diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -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) diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -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.