changeset 4970:30d4d8985dd8

transactions: avoid late tear-down (issue641) We use weak references (ugh) to avoid having to manually delete transaction references out of each call frame when an exception occurs.
author Matt Mackall <mpm@selenic.com>
date Sun, 22 Jul 2007 14:53:57 -0500
parents b43db44cd047
children 3e6dae278c99
files hgext/mq.py mercurial/localrepo.py tests/test-bundle-r.out tests/test-commit.out tests/test-encoding.out tests/test-hup.out tests/test-parse-date.out
diffstat 7 files changed, 20 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -442,7 +442,7 @@ class queue:
             lock = repo.lock()
             tr = repo.transaction()
             try:
-                ret = self._apply(tr, repo, series, list, update_status,
+                ret = self._apply(repo, series, list, update_status,
                                   strict, patchdir, merge, all_files=all_files)
                 tr.close()
                 self.save_dirty()
@@ -457,7 +457,7 @@ class queue:
         finally:
             del lock, wlock, tr
 
-    def _apply(self, tr, repo, series, list=False, update_status=True,
+    def _apply(self, repo, series, list=False, update_status=True,
                strict=False, patchdir=None, merge=None, all_files={}):
         # TODO unify with commands.py
         if not patchdir:
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -587,7 +587,7 @@ class localrepository(repo.repository):
         self._wlockref = weakref.ref(l)
         return l
 
-    def filecommit(self, fn, manifest1, manifest2, linkrev, transaction, changelist):
+    def filecommit(self, fn, manifest1, manifest2, linkrev, tr, changelist):
         """
         commit an individual file as part of a larger transaction
         """
@@ -645,7 +645,7 @@ class localrepository(repo.repository):
             return fp1
 
         changelist.append(fn)
-        return fl.add(t, meta, transaction, linkrev, fp1, fp2)
+        return fl.add(t, meta, tr, linkrev, fp1, fp2)
 
     def rawcommit(self, files, text, user, date, p1=None, p2=None, extra={}):
         if p1 is None:
@@ -719,6 +719,7 @@ class localrepository(repo.repository):
             wlock = self.wlock()
             lock = self.lock()
             tr = self.transaction()
+            trp = weakref.proxy(tr)
 
             # check in files
             new = {}
@@ -729,7 +730,7 @@ class localrepository(repo.repository):
             for f in commit:
                 self.ui.note(f + "\n")
                 try:
-                    new[f] = self.filecommit(f, m1, m2, linkrev, tr, changed)
+                    new[f] = self.filecommit(f, m1, m2, linkrev, trp, changed)
                     new_exec = is_exec(f)
                     new_link = is_link(f)
                     if not changed or changed[-1] != f:
@@ -759,7 +760,7 @@ class localrepository(repo.repository):
                     removed.append(f)
                 elif f in m2:
                     removed.append(f)
-            mn = self.manifest.add(m1, tr, linkrev, c1[0], c2[0],
+            mn = self.manifest.add(m1, trp, linkrev, c1[0], c2[0],
                                    (new, removed))
 
             # add changeset
@@ -796,7 +797,7 @@ class localrepository(repo.repository):
             text = '\n'.join(lines)
             if branchname:
                 extra["branch"] = branchname
-            n = self.changelog.add(mn, changed + removed, text, tr, p1, p2,
+            n = self.changelog.add(mn, changed + removed, text, trp, p1, p2,
                                    user, date, extra)
             self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
                       parent2=xp2)
@@ -1831,11 +1832,12 @@ class localrepository(repo.repository):
 
         tr = self.transaction()
         try:
+            trp = weakref.proxy(tr)
             # pull off the changeset group
             self.ui.status(_("adding changesets\n"))
             cor = cl.count() - 1
             chunkiter = changegroup.chunkiter(source)
-            if cl.addgroup(chunkiter, csmap, tr, 1) is None:
+            if cl.addgroup(chunkiter, csmap, trp, 1) is None:
                 raise util.Abort(_("received changelog group is empty"))
             cnr = cl.count() - 1
             changesets = cnr - cor
@@ -1847,7 +1849,7 @@ class localrepository(repo.repository):
             # if the result of the merge of 1 and 2 is the same in 3 and 4,
             # no new manifest will be created and the manifest group will
             # be empty during the pull
-            self.manifest.addgroup(chunkiter, revmap, tr)
+            self.manifest.addgroup(chunkiter, revmap, trp)
 
             # process the files
             self.ui.status(_("adding file changes\n"))
@@ -1859,13 +1861,13 @@ class localrepository(repo.repository):
                 fl = self.file(f)
                 o = fl.count()
                 chunkiter = changegroup.chunkiter(source)
-                if fl.addgroup(chunkiter, revmap, tr) is None:
+                if fl.addgroup(chunkiter, revmap, trp) is None:
                     raise util.Abort(_("received file revlog group is empty"))
                 revisions += fl.count() - o
                 files += 1
 
             # make changelog see real files again
-            cl.finalize(tr)
+            cl.finalize(trp)
 
             newheads = len(self.changelog.heads())
             heads = ""
--- a/tests/test-bundle-r.out
+++ b/tests/test-bundle-r.out
@@ -152,9 +152,9 @@ 1 files updated, 0 files merged, 0 files
 % 2
 2:d62976ca1e50
 adding changesets
-abort: unknown parent ac69c658229d!
 transaction abort!
 rollback completed
+abort: unknown parent ac69c658229d!
 % 2
 2:d62976ca1e50
 adding changesets
--- a/tests/test-commit.out
+++ b/tests/test-commit.out
@@ -1,4 +1,6 @@
 % commit date test
+transaction abort!
+rollback completed
 abort: impossible time zone offset: 4444444
 transaction abort!
 rollback completed
@@ -6,8 +8,6 @@ abort: invalid date: '1\t15.1'
 transaction abort!
 rollback completed
 abort: invalid date: 'foo bar' 
-transaction abort!
-rollback completed
 nothing changed
 % partial commit test
 trouble committing bar!
--- a/tests/test-encoding.out
+++ b/tests/test-encoding.out
@@ -9,9 +9,9 @@ M a
 ? latin-1
 ? latin-1-tag
 ? utf-8
-abort: decoding near ' encoded: é': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)!
 transaction abort!
 rollback completed
+abort: decoding near ' encoded: é': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)!
 % these should work
 marked working directory as branch é
 % ascii
--- a/tests/test-hup.out
+++ b/tests/test-hup.out
@@ -1,7 +1,7 @@
 0
 0
 adding changesets
-killed!
 transaction abort!
 rollback completed
+killed!
 .hg/00changelog.i .hg/journal.dirstate .hg/requires .hg/store .hg/store/00changelog.i .hg/store/00changelog.i.a
--- a/tests/test-parse-date.out
+++ b/tests/test-parse-date.out
@@ -3,6 +3,8 @@ changeset 3:107ce1ee2b43 backs out chang
 merging with changeset 2:e6c3abc120e7
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
+transaction abort!
+rollback completed
 abort: invalid date: 'should fail' 
 transaction abort!
 rollback completed
@@ -10,8 +12,6 @@ abort: date exceeds 32 bits: 10000000000
 transaction abort!
 rollback completed
 abort: impossible time zone offset: 1400000
-transaction abort!
-rollback completed
 Sun Jan 15 13:30:00 2006 +0500
 Sun Jan 15 13:30:00 2006 -0800
 Sat Jul 15 13:30:00 2006 +0500