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.
--- a/hgext/mq.py Sun Jul 22 16:21:49 2007 +0200
+++ b/hgext/mq.py Sun Jul 22 14:53:57 2007 -0500
@@ -442,7 +442,7 @@
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 @@
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 Sun Jul 22 16:21:49 2007 +0200
+++ b/mercurial/localrepo.py Sun Jul 22 14:53:57 2007 -0500
@@ -587,7 +587,7 @@
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 @@
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 @@
wlock = self.wlock()
lock = self.lock()
tr = self.transaction()
+ trp = weakref.proxy(tr)
# check in files
new = {}
@@ -729,7 +730,7 @@
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 @@
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 @@
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 @@
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 @@
# 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 @@
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 Sun Jul 22 16:21:49 2007 +0200
+++ b/tests/test-bundle-r.out Sun Jul 22 14:53:57 2007 -0500
@@ -152,9 +152,9 @@
% 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 Sun Jul 22 16:21:49 2007 +0200
+++ b/tests/test-commit.out Sun Jul 22 14:53:57 2007 -0500
@@ -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 @@
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 Sun Jul 22 16:21:49 2007 +0200
+++ b/tests/test-encoding.out Sun Jul 22 14:53:57 2007 -0500
@@ -9,9 +9,9 @@
? 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 Sun Jul 22 16:21:49 2007 +0200
+++ b/tests/test-hup.out Sun Jul 22 14:53:57 2007 -0500
@@ -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 Sun Jul 22 16:21:49 2007 +0200
+++ b/tests/test-parse-date.out Sun Jul 22 14:53:57 2007 -0500
@@ -3,6 +3,8 @@
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 @@
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