changeset 27867:7ced54ebf972

with: use context manager for transaction in changegroup apply (This needs some line wrapping due to the additional indent level. -mpm)
author Bryan O'Sullivan <bryano@fb.com>
date Fri, 15 Jan 2016 13:14:50 -0800
parents f54bf1f41566
children d1a55366d825
files mercurial/changegroup.py
diffstat 1 files changed, 140 insertions(+), 137 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/changegroup.py	Fri Jan 15 13:14:48 2016 -0800
+++ b/mercurial/changegroup.py	Fri Jan 15 13:14:50 2016 -0800
@@ -323,162 +323,165 @@
 
         changesets = files = revisions = 0
 
-        tr = repo.transaction("\n".join([srctype, util.hidepassword(url)]))
         try:
-            # The transaction could have been created before and already
-            # carries source information. In this case we use the top
-            # level data. We overwrite the argument because we need to use
-            # the top level value (if they exist) in this function.
-            srctype = tr.hookargs.setdefault('source', srctype)
-            url = tr.hookargs.setdefault('url', url)
-            repo.hook('prechangegroup', throw=True, **tr.hookargs)
+            with repo.transaction("\n".join([srctype,
+                                             util.hidepassword(url)])) as tr:
+                # The transaction could have been created before and already
+                # carries source information. In this case we use the top
+                # level data. We overwrite the argument because we need to use
+                # the top level value (if they exist) in this function.
+                srctype = tr.hookargs.setdefault('source', srctype)
+                url = tr.hookargs.setdefault('url', url)
+                repo.hook('prechangegroup', throw=True, **tr.hookargs)
 
-            # write changelog data to temp files so concurrent readers
-            # will not see an inconsistent view
-            cl = repo.changelog
-            cl.delayupdate(tr)
-            oldheads = cl.heads()
+                # write changelog data to temp files so concurrent readers
+                # will not see an inconsistent view
+                cl = repo.changelog
+                cl.delayupdate(tr)
+                oldheads = cl.heads()
 
-            trp = weakref.proxy(tr)
-            # pull off the changeset group
-            repo.ui.status(_("adding changesets\n"))
-            clstart = len(cl)
-            class prog(object):
-                def __init__(self, step, total):
-                    self._step = step
-                    self._total = total
-                    self._count = 1
-                def __call__(self):
-                    repo.ui.progress(self._step, self._count, unit=_('chunks'),
-                                     total=self._total)
-                    self._count += 1
-            self.callback = prog(_('changesets'), expectedtotal)
+                trp = weakref.proxy(tr)
+                # pull off the changeset group
+                repo.ui.status(_("adding changesets\n"))
+                clstart = len(cl)
+                class prog(object):
+                    def __init__(self, step, total):
+                        self._step = step
+                        self._total = total
+                        self._count = 1
+                    def __call__(self):
+                        repo.ui.progress(self._step, self._count,
+                                         unit=_('chunks'), total=self._total)
+                        self._count += 1
+                self.callback = prog(_('changesets'), expectedtotal)
 
-            efiles = set()
-            def onchangelog(cl, node):
-                efiles.update(cl.read(node)[3])
+                efiles = set()
+                def onchangelog(cl, node):
+                    efiles.update(cl.read(node)[3])
 
-            self.changelogheader()
-            srccontent = cl.addgroup(self, csmap, trp,
-                                     addrevisioncb=onchangelog)
-            efiles = len(efiles)
+                self.changelogheader()
+                srccontent = cl.addgroup(self, csmap, trp,
+                                         addrevisioncb=onchangelog)
+                efiles = len(efiles)
 
-            if not (srccontent or emptyok):
-                raise error.Abort(_("received changelog group is empty"))
-            clend = len(cl)
-            changesets = clend - clstart
-            repo.ui.progress(_('changesets'), None)
+                if not (srccontent or emptyok):
+                    raise error.Abort(_("received changelog group is empty"))
+                clend = len(cl)
+                changesets = clend - clstart
+                repo.ui.progress(_('changesets'), None)
 
-            # pull off the manifest group
-            repo.ui.status(_("adding manifests\n"))
-            self._unpackmanifests(repo, revmap, trp, prog, changesets)
+                # pull off the manifest group
+                repo.ui.status(_("adding manifests\n"))
+                self._unpackmanifests(repo, revmap, trp, prog, changesets)
 
-            needfiles = {}
-            if repo.ui.configbool('server', 'validate', default=False):
-                # validate incoming csets have their manifests
-                for cset in xrange(clstart, clend):
-                    mfnode = repo.changelog.read(repo.changelog.node(cset))[0]
-                    mfest = repo.manifest.readdelta(mfnode)
-                    # store file nodes we must see
-                    for f, n in mfest.iteritems():
-                        needfiles.setdefault(f, set()).add(n)
+                needfiles = {}
+                if repo.ui.configbool('server', 'validate', default=False):
+                    # validate incoming csets have their manifests
+                    for cset in xrange(clstart, clend):
+                        mfnode = repo.changelog.read(
+                            repo.changelog.node(cset))[0]
+                        mfest = repo.manifest.readdelta(mfnode)
+                        # store file nodes we must see
+                        for f, n in mfest.iteritems():
+                            needfiles.setdefault(f, set()).add(n)
 
-            # process the files
-            repo.ui.status(_("adding file changes\n"))
-            self.callback = None
-            pr = prog(_('files'), efiles)
-            newrevs, newfiles = _addchangegroupfiles(
-                repo, self, revmap, trp, pr, needfiles)
-            revisions += newrevs
-            files += newfiles
+                # process the files
+                repo.ui.status(_("adding file changes\n"))
+                self.callback = None
+                pr = prog(_('files'), efiles)
+                newrevs, newfiles = _addchangegroupfiles(
+                    repo, self, revmap, trp, pr, needfiles)
+                revisions += newrevs
+                files += newfiles
 
-            dh = 0
-            if oldheads:
-                heads = cl.heads()
-                dh = len(heads) - len(oldheads)
-                for h in heads:
-                    if h not in oldheads and repo[h].closesbranch():
-                        dh -= 1
-            htext = ""
-            if dh:
-                htext = _(" (%+d heads)") % dh
+                dh = 0
+                if oldheads:
+                    heads = cl.heads()
+                    dh = len(heads) - len(oldheads)
+                    for h in heads:
+                        if h not in oldheads and repo[h].closesbranch():
+                            dh -= 1
+                htext = ""
+                if dh:
+                    htext = _(" (%+d heads)") % dh
 
-            repo.ui.status(_("added %d changesets"
-                             " with %d changes to %d files%s\n")
-                             % (changesets, revisions, files, htext))
-            repo.invalidatevolatilesets()
+                repo.ui.status(_("added %d changesets"
+                                 " with %d changes to %d files%s\n")
+                                 % (changesets, revisions, files, htext))
+                repo.invalidatevolatilesets()
 
-            if changesets > 0:
-                if 'node' not in tr.hookargs:
-                    tr.hookargs['node'] = hex(cl.node(clstart))
-                    tr.hookargs['node_last'] = hex(cl.node(clend - 1))
-                    hookargs = dict(tr.hookargs)
-                else:
-                    hookargs = dict(tr.hookargs)
-                    hookargs['node'] = hex(cl.node(clstart))
-                    hookargs['node_last'] = hex(cl.node(clend - 1))
-                repo.hook('pretxnchangegroup', throw=True, **hookargs)
+                if changesets > 0:
+                    if 'node' not in tr.hookargs:
+                        tr.hookargs['node'] = hex(cl.node(clstart))
+                        tr.hookargs['node_last'] = hex(cl.node(clend - 1))
+                        hookargs = dict(tr.hookargs)
+                    else:
+                        hookargs = dict(tr.hookargs)
+                        hookargs['node'] = hex(cl.node(clstart))
+                        hookargs['node_last'] = hex(cl.node(clend - 1))
+                    repo.hook('pretxnchangegroup', throw=True, **hookargs)
 
-            added = [cl.node(r) for r in xrange(clstart, clend)]
-            publishing = repo.publishing()
-            if srctype in ('push', 'serve'):
-                # Old servers can not push the boundary themselves.
-                # New servers won't push the boundary if changeset already
-                # exists locally as secret
-                #
-                # We should not use added here but the list of all change in
-                # the bundle
-                if publishing:
-                    phases.advanceboundary(repo, tr, phases.public, srccontent)
-                else:
-                    # Those changesets have been pushed from the outside, their
-                    # phases are going to be pushed alongside. Therefor
-                    # `targetphase` is ignored.
-                    phases.advanceboundary(repo, tr, phases.draft, srccontent)
-                    phases.retractboundary(repo, tr, phases.draft, added)
-            elif srctype != 'strip':
-                # publishing only alter behavior during push
-                #
-                # strip should not touch boundary at all
-                phases.retractboundary(repo, tr, targetphase, added)
-
-            if changesets > 0:
-                if srctype != 'strip':
-                    # During strip, branchcache is invalid but coming call to
-                    # `destroyed` will repair it.
-                    # In other case we can safely update cache on disk.
-                    branchmap.updatecache(repo.filtered('served'))
+                added = [cl.node(r) for r in xrange(clstart, clend)]
+                publishing = repo.publishing()
+                if srctype in ('push', 'serve'):
+                    # Old servers can not push the boundary themselves.
+                    # New servers won't push the boundary if changeset already
+                    # exists locally as secret
+                    #
+                    # We should not use added here but the list of all change in
+                    # the bundle
+                    if publishing:
+                        phases.advanceboundary(repo, tr, phases.public,
+                                               srccontent)
+                    else:
+                        # Those changesets have been pushed from the
+                        # outside, their phases are going to be pushed
+                        # alongside. Therefor `targetphase` is
+                        # ignored.
+                        phases.advanceboundary(repo, tr, phases.draft,
+                                               srccontent)
+                        phases.retractboundary(repo, tr, phases.draft, added)
+                elif srctype != 'strip':
+                    # publishing only alter behavior during push
+                    #
+                    # strip should not touch boundary at all
+                    phases.retractboundary(repo, tr, targetphase, added)
 
-                def runhooks():
-                    # These hooks run when the lock releases, not when the
-                    # transaction closes. So it's possible for the changelog
-                    # to have changed since we last saw it.
-                    if clstart >= len(repo):
-                        return
+                if changesets > 0:
+                    if srctype != 'strip':
+                        # During strip, branchcache is invalid but
+                        # coming call to `destroyed` will repair it.
+                        # In other case we can safely update cache on
+                        # disk.
+                        branchmap.updatecache(repo.filtered('served'))
 
-                    # forcefully update the on-disk branch cache
-                    repo.ui.debug("updating the branch cache\n")
-                    repo.hook("changegroup", **hookargs)
+                    def runhooks():
+                        # These hooks run when the lock releases, not when the
+                        # transaction closes. So it's possible for the changelog
+                        # to have changed since we last saw it.
+                        if clstart >= len(repo):
+                            return
 
-                    for n in added:
-                        args = hookargs.copy()
-                        args['node'] = hex(n)
-                        del args['node_last']
-                        repo.hook("incoming", **args)
+                        # forcefully update the on-disk branch cache
+                        repo.ui.debug("updating the branch cache\n")
+                        repo.hook("changegroup", **hookargs)
+
+                        for n in added:
+                            args = hookargs.copy()
+                            args['node'] = hex(n)
+                            del args['node_last']
+                            repo.hook("incoming", **args)
 
-                    newheads = [h for h in repo.heads() if h not in oldheads]
-                    repo.ui.log("incoming",
-                                "%s incoming changes - new heads: %s\n",
-                                len(added),
-                                ', '.join([hex(c[:6]) for c in newheads]))
+                        newheads = [h for h in repo.heads()
+                                    if h not in oldheads]
+                        repo.ui.log("incoming",
+                                    "%s incoming changes - new heads: %s\n",
+                                    len(added),
+                                    ', '.join([hex(c[:6]) for c in newheads]))
 
-                tr.addpostclose('changegroup-runhooks-%020i' % clstart,
-                                lambda tr: repo._afterlock(runhooks))
-
-            tr.close()
-
+                    tr.addpostclose('changegroup-runhooks-%020i' % clstart,
+                                    lambda tr: repo._afterlock(runhooks))
         finally:
-            tr.release()
             repo.ui.flush()
         # never return 0 here:
         if dh < 0: