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)