diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -613,8 +613,7 @@ class queue(object): repo.dirstate.invalidate() raise finally: - del tr - release(lock, wlock) + release(tr, lock, wlock) self.removeundo(repo) def _apply(self, repo, series, list=False, update_status=True, diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -971,7 +971,8 @@ class localrepository(repo.repository): self.branchtags() return n finally: - del tr + if tr: + tr.release() lock.release() def destroyed(self): @@ -2194,7 +2195,7 @@ class localrepository(repo.repository): tr.close() finally: - del tr + tr.release() if changesets > 0: # forcefully update the on-disk branch cache diff --git a/mercurial/transaction.py b/mercurial/transaction.py --- a/mercurial/transaction.py +++ b/mercurial/transaction.py @@ -43,6 +43,7 @@ def _playback(journal, report, opener, e class transaction(object): def __init__(self, report, opener, journal, after=None, createmode=None): self.count = 1 + self.usages = 1 self.report = report self.opener = opener self.after = after @@ -108,8 +109,16 @@ class transaction(object): @active def nest(self): self.count += 1 + self.usages += 1 return self + def release(self): + if self.count > 0: + self.usages -= 1 + # of the transaction scopes are left without being closed, fail + if self.count > 0 and self.usages == 0: + self._abort() + def running(self): return self.count > 0 @@ -136,6 +145,7 @@ class transaction(object): def _abort(self): self.count = 0 + self.usages = 0 self.file.close() try: