Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 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 | 126f527b3ba3 |
children | 7f5c3fb0a37d |
comparison
equal
deleted
inserted
replaced
4969:b43db44cd047 | 4970:30d4d8985dd8 |
---|---|
585 self.dirstate.invalidate, _('working directory of %s') % | 585 self.dirstate.invalidate, _('working directory of %s') % |
586 self.origroot) | 586 self.origroot) |
587 self._wlockref = weakref.ref(l) | 587 self._wlockref = weakref.ref(l) |
588 return l | 588 return l |
589 | 589 |
590 def filecommit(self, fn, manifest1, manifest2, linkrev, transaction, changelist): | 590 def filecommit(self, fn, manifest1, manifest2, linkrev, tr, changelist): |
591 """ | 591 """ |
592 commit an individual file as part of a larger transaction | 592 commit an individual file as part of a larger transaction |
593 """ | 593 """ |
594 | 594 |
595 t = self.wread(fn) | 595 t = self.wread(fn) |
643 # is the file unmodified from the parent? report existing entry | 643 # is the file unmodified from the parent? report existing entry |
644 if fp2 == nullid and not fl.cmp(fp1, t): | 644 if fp2 == nullid and not fl.cmp(fp1, t): |
645 return fp1 | 645 return fp1 |
646 | 646 |
647 changelist.append(fn) | 647 changelist.append(fn) |
648 return fl.add(t, meta, transaction, linkrev, fp1, fp2) | 648 return fl.add(t, meta, tr, linkrev, fp1, fp2) |
649 | 649 |
650 def rawcommit(self, files, text, user, date, p1=None, p2=None, extra={}): | 650 def rawcommit(self, files, text, user, date, p1=None, p2=None, extra={}): |
651 if p1 is None: | 651 if p1 is None: |
652 p1, p2 = self.dirstate.parents() | 652 p1, p2 = self.dirstate.parents() |
653 return self.commit(files=files, text=text, user=user, date=date, | 653 return self.commit(files=files, text=text, user=user, date=date, |
717 self.hook("precommit", throw=True, parent1=xp1, parent2=xp2) | 717 self.hook("precommit", throw=True, parent1=xp1, parent2=xp2) |
718 | 718 |
719 wlock = self.wlock() | 719 wlock = self.wlock() |
720 lock = self.lock() | 720 lock = self.lock() |
721 tr = self.transaction() | 721 tr = self.transaction() |
722 trp = weakref.proxy(tr) | |
722 | 723 |
723 # check in files | 724 # check in files |
724 new = {} | 725 new = {} |
725 linkrev = self.changelog.count() | 726 linkrev = self.changelog.count() |
726 commit.sort() | 727 commit.sort() |
727 is_exec = util.execfunc(self.root, m1.execf) | 728 is_exec = util.execfunc(self.root, m1.execf) |
728 is_link = util.linkfunc(self.root, m1.linkf) | 729 is_link = util.linkfunc(self.root, m1.linkf) |
729 for f in commit: | 730 for f in commit: |
730 self.ui.note(f + "\n") | 731 self.ui.note(f + "\n") |
731 try: | 732 try: |
732 new[f] = self.filecommit(f, m1, m2, linkrev, tr, changed) | 733 new[f] = self.filecommit(f, m1, m2, linkrev, trp, changed) |
733 new_exec = is_exec(f) | 734 new_exec = is_exec(f) |
734 new_link = is_link(f) | 735 new_link = is_link(f) |
735 if not changed or changed[-1] != f: | 736 if not changed or changed[-1] != f: |
736 # mention the file in the changelog if some | 737 # mention the file in the changelog if some |
737 # flag changed, even if there was no content | 738 # flag changed, even if there was no content |
757 if f in m1: | 758 if f in m1: |
758 del m1[f] | 759 del m1[f] |
759 removed.append(f) | 760 removed.append(f) |
760 elif f in m2: | 761 elif f in m2: |
761 removed.append(f) | 762 removed.append(f) |
762 mn = self.manifest.add(m1, tr, linkrev, c1[0], c2[0], | 763 mn = self.manifest.add(m1, trp, linkrev, c1[0], c2[0], |
763 (new, removed)) | 764 (new, removed)) |
764 | 765 |
765 # add changeset | 766 # add changeset |
766 new = new.keys() | 767 new = new.keys() |
767 new.sort() | 768 new.sort() |
794 if not lines: | 795 if not lines: |
795 return None | 796 return None |
796 text = '\n'.join(lines) | 797 text = '\n'.join(lines) |
797 if branchname: | 798 if branchname: |
798 extra["branch"] = branchname | 799 extra["branch"] = branchname |
799 n = self.changelog.add(mn, changed + removed, text, tr, p1, p2, | 800 n = self.changelog.add(mn, changed + removed, text, trp, p1, p2, |
800 user, date, extra) | 801 user, date, extra) |
801 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1, | 802 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1, |
802 parent2=xp2) | 803 parent2=xp2) |
803 tr.close() | 804 tr.close() |
804 | 805 |
1829 cl.delayupdate() | 1830 cl.delayupdate() |
1830 oldheads = len(cl.heads()) | 1831 oldheads = len(cl.heads()) |
1831 | 1832 |
1832 tr = self.transaction() | 1833 tr = self.transaction() |
1833 try: | 1834 try: |
1835 trp = weakref.proxy(tr) | |
1834 # pull off the changeset group | 1836 # pull off the changeset group |
1835 self.ui.status(_("adding changesets\n")) | 1837 self.ui.status(_("adding changesets\n")) |
1836 cor = cl.count() - 1 | 1838 cor = cl.count() - 1 |
1837 chunkiter = changegroup.chunkiter(source) | 1839 chunkiter = changegroup.chunkiter(source) |
1838 if cl.addgroup(chunkiter, csmap, tr, 1) is None: | 1840 if cl.addgroup(chunkiter, csmap, trp, 1) is None: |
1839 raise util.Abort(_("received changelog group is empty")) | 1841 raise util.Abort(_("received changelog group is empty")) |
1840 cnr = cl.count() - 1 | 1842 cnr = cl.count() - 1 |
1841 changesets = cnr - cor | 1843 changesets = cnr - cor |
1842 | 1844 |
1843 # pull off the manifest group | 1845 # pull off the manifest group |
1845 chunkiter = changegroup.chunkiter(source) | 1847 chunkiter = changegroup.chunkiter(source) |
1846 # no need to check for empty manifest group here: | 1848 # no need to check for empty manifest group here: |
1847 # if the result of the merge of 1 and 2 is the same in 3 and 4, | 1849 # if the result of the merge of 1 and 2 is the same in 3 and 4, |
1848 # no new manifest will be created and the manifest group will | 1850 # no new manifest will be created and the manifest group will |
1849 # be empty during the pull | 1851 # be empty during the pull |
1850 self.manifest.addgroup(chunkiter, revmap, tr) | 1852 self.manifest.addgroup(chunkiter, revmap, trp) |
1851 | 1853 |
1852 # process the files | 1854 # process the files |
1853 self.ui.status(_("adding file changes\n")) | 1855 self.ui.status(_("adding file changes\n")) |
1854 while 1: | 1856 while 1: |
1855 f = changegroup.getchunk(source) | 1857 f = changegroup.getchunk(source) |
1857 break | 1859 break |
1858 self.ui.debug(_("adding %s revisions\n") % f) | 1860 self.ui.debug(_("adding %s revisions\n") % f) |
1859 fl = self.file(f) | 1861 fl = self.file(f) |
1860 o = fl.count() | 1862 o = fl.count() |
1861 chunkiter = changegroup.chunkiter(source) | 1863 chunkiter = changegroup.chunkiter(source) |
1862 if fl.addgroup(chunkiter, revmap, tr) is None: | 1864 if fl.addgroup(chunkiter, revmap, trp) is None: |
1863 raise util.Abort(_("received file revlog group is empty")) | 1865 raise util.Abort(_("received file revlog group is empty")) |
1864 revisions += fl.count() - o | 1866 revisions += fl.count() - o |
1865 files += 1 | 1867 files += 1 |
1866 | 1868 |
1867 # make changelog see real files again | 1869 # make changelog see real files again |
1868 cl.finalize(tr) | 1870 cl.finalize(trp) |
1869 | 1871 |
1870 newheads = len(self.changelog.heads()) | 1872 newheads = len(self.changelog.heads()) |
1871 heads = "" | 1873 heads = "" |
1872 if oldheads and newheads != oldheads: | 1874 if oldheads and newheads != oldheads: |
1873 heads = _(" (%+d heads)") % (newheads - oldheads) | 1875 heads = _(" (%+d heads)") % (newheads - oldheads) |