[PATCH 1 of 2] discovery: diet discovery.prepush from non-discovery code

Christian Ebert blacktrash at gmx.net
Mon Jan 23 11:01:52 CST 2012


* pierre-yves.david at logilab.fr on Thursday, January 19, 2012 at 16:10:02 +0100
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david at logilab.fr>
> # Date 1326984655 -3600
> # Node ID 65167145e2d3658699e881a936f2da4f718fb205
> # Parent  917d914e5a9232cac95b99687841448f68758ec2
> discovery: diet discovery.prepush from non-discovery code
> 
> The ``discovery.prepush`` function was doing multiple things not related to
> discovery. This changeset move some code into the ``localrepo.push`` method. The
> old ``discovery.prepush`` function jobs is now restricted to checking for
> multple head creation. It was then renamed ``discovery.checkheads``.
> 
> This new ``discovery.checkheads`` function may receive several other changes in
> the future but we are a bit too much near the freeze for a wider refactoring.
> 
> diff --git a/mercurial/discovery.py b/mercurial/discovery.py
> --- a/mercurial/discovery.py
> +++ b/mercurial/discovery.py
> @@ -130,148 +130,110 @@ def findcommonoutgoing(repo, other, only
>             missingheads = onlyheads
>         og.missingheads = missingheads
> 
>     return og
> 
> -def prepush(repo, remote, force, revs, newbranch):
> -    '''Analyze the local and remote repositories and determine which
> -    changesets need to be pushed to the remote. Return value depends
> -    on circumstances:
> +def checkheads(repo, remote, outgoing, remoteheads, newbranch=False):
> +    """Check that a push won't add any outgoing head
> 
> -    If we are not going to push anything, return a tuple (None, 1,
> -    common) The third element "common" is the list of heads of the
> -    common set between local and remote.
> -
> -    Otherwise, return a tuple (changegroup, remoteheads, futureheads),
> -    where changegroup is a readable file-like object whose read()
> -    returns successive changegroup chunks ready to be sent over the
> -    wire, remoteheads is the list of remote heads and futureheads is
> -    the list of heads of the common set between local and remote to
> -    be after push completion.
> -    '''
> -    commoninc = findcommonincoming(repo, remote, force=force)
> -    outgoing = findcommonoutgoing(repo, remote, onlyheads=revs,
> -                                      commoninc=commoninc, force=force)
> -    _common, inc, remoteheads = commoninc
> +    raise Abort error and display ui message as needed.
> +    """
> +    if remoteheads == [nullid]:
> +        # remote is empty, nothing to check.
> +        return
> 
>     cl = repo.changelog
> -    outg = outgoing.missing
> -    common = outgoing.commonheads
> +    if remote.capable('branchmap'):
> +        # Check for each named branch if we're creating new remote heads.
> +        # To be a remote head after push, node must be either:
> +        # - unknown locally
> +        # - a local outgoing head descended from update
> +        # - a remote head that's known locally and not
> +        #   ancestral to an outgoing head
> 
> -    if not outg:
> -        if outgoing.excluded:
> -            repo.ui.status(_("no changes to push but %i secret changesets\n")
> -                           % len(outgoing.excluded))
> -        else:
> -            repo.ui.status(_("no changes found\n"))
> -        return None, 1, common
> +        # 1. Create set of branches involved in the push.
> +        branches = set(repo[n].branch() for n in outgoing.missing)
> 
> -    if not force and remoteheads != [nullid]:
> -        if remote.capable('branchmap'):
> -            # Check for each named branch if we're creating new remote heads.
> -            # To be a remote head after push, node must be either:
> -            # - unknown locally
> -            # - a local outgoing head descended from update
> -            # - a remote head that's known locally and not
> -            #   ancestral to an outgoing head
> +        # 2. Check for new branches on the remote.
> +        remotemap = remote.branchmap()
> +        newbranches = branches - set(remotemap)
> +        if newbranches and not newbranch: # new branch requires --new-branch
> +            branchnames = ', '.join(sorted(newbranches))
> +            raise util.Abort(_("push creates new remote branches: %s!")
> +                               % branchnames,
> +                             hint=_("use 'hg push --new-branch' to create"
> +                                    " new remote branches"))
> +        branches.difference_update(newbranches)
> 
> -            # 1. Create set of branches involved in the push.
> -            branches = set(repo[n].branch() for n in outg)
> +        # 3. Construct the initial oldmap and newmap dicts.
> +        # They contain information about the remote heads before and
> +        # after the push, respectively.
> +        # Heads not found locally are not included in either dict,
> +        # since they won't be affected by the push.
> +        # unsynced contains all branches with incoming changesets.
> +        oldmap = {}
> +        newmap = {}
> +        unsynced = set()
> +        for branch in branches:
> +            remotebrheads = remotemap[branch]
> +            prunedbrheads = [h for h in remotebrheads if h in cl.nodemap]
> +            oldmap[branch] = prunedbrheads
> +            newmap[branch] = list(prunedbrheads)
> +            if len(remotebrheads) > len(prunedbrheads):
> +                unsynced.add(branch)
> 
> -            # 2. Check for new branches on the remote.
> -            remotemap = remote.branchmap()
> -            newbranches = branches - set(remotemap)
> -            if newbranches and not newbranch: # new branch requires --new-branch
> -                branchnames = ', '.join(sorted(newbranches))
> -                raise util.Abort(_("push creates new remote branches: %s!")
> -                                   % branchnames,
> -                                 hint=_("use 'hg push --new-branch' to create"
> -                                        " new remote branches"))
> -            branches.difference_update(newbranches)
> +        # 4. Update newmap with outgoing changes.
> +        # This will possibly add new heads and remove existing ones.
> +        ctxgen = (repo[n] for n in outgoing.missing)
> +        repo._updatebranchcache(newmap, ctxgen)
> 
> -            # 3. Construct the initial oldmap and newmap dicts.
> -            # They contain information about the remote heads before and
> -            # after the push, respectively.
> -            # Heads not found locally are not included in either dict,
> -            # since they won't be affected by the push.
> -            # unsynced contains all branches with incoming changesets.
> -            oldmap = {}
> -            newmap = {}
> -            unsynced = set()
> -            for branch in branches:
> -                remotebrheads = remotemap[branch]
> -                prunedbrheads = [h for h in remotebrheads if h in cl.nodemap]
> -                oldmap[branch] = prunedbrheads
> -                newmap[branch] = list(prunedbrheads)
> -                if len(remotebrheads) > len(prunedbrheads):
> -                    unsynced.add(branch)
> +    else:
> +        # 1-4b. old servers: Check for new topological heads.
> +        # Construct {old,new}map with branch = None (topological branch).
> +        # (code based on _updatebranchcache)
> +        oldheads = set(h for h in remoteheads if h in cl.nodemap)
> +        newheads = oldheads.union(outg)

This yields a name error here:

$ hg push
pushing to ssh://<some repo>
searching for changes
** unknown exception encountered, please report by visiting
**  http://mercurial.selenic.com/wiki/BugTracker
** Python 2.7.2 (default, Dec 30 2011, 19:40:58) [GCC 4.0.1 (Apple Inc. build 5493)]
** Mercurial Distributed SCM (version 2.1-rc+7-610c4434973b)
** Extensions loaded:
Traceback (most recent call last):
  File "/usr/local/bin/hg", line 38, in <module>
    mercurial.dispatch.run()
  File "/usr/local/lib/python2.7/site-packages/mercurial/dispatch.py", line 27, in run
    sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
  File "/usr/local/lib/python2.7/site-packages/mercurial/dispatch.py", line 64, in dispatch
    return _runcatch(req)
  File "/usr/local/lib/python2.7/site-packages/mercurial/dispatch.py", line 87, in _runcatch
    return _dispatch(req)
  File "/usr/local/lib/python2.7/site-packages/mercurial/dispatch.py", line 683, in _dispatch
    cmdpats, cmdoptions)
  File "/usr/local/lib/python2.7/site-packages/mercurial/dispatch.py", line 465, in runcommand
    ret = _runcommand(ui, options, cmd, d)
  File "/usr/local/lib/python2.7/site-packages/mercurial/dispatch.py", line 737, in _runcommand
    return checkargs()
  File "/usr/local/lib/python2.7/site-packages/mercurial/dispatch.py", line 691, in checkargs
    return cmdfunc()
  File "/usr/local/lib/python2.7/site-packages/mercurial/dispatch.py", line 680, in <lambda>
    d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
  File "/usr/local/lib/python2.7/site-packages/mercurial/util.py", line 456, in check
    return func(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/mercurial/commands.py", line 4417, in push
    newbranch=opts.get('new_branch'))
  File "/usr/local/lib/python2.7/site-packages/mercurial/localrepo.py", line 1638, in push
    remoteheads, newbranch)
  File "/usr/local/lib/python2.7/site-packages/mercurial/discovery.py", line 193, in checkheads
    newheads = oldheads.union(outg)
NameError: global name 'outg' is not defined


c
-- 
theatre - books - texts - movies
Black Trash Productions at home: http://www.blacktrash.org
Black Trash Productions on Facebook:
http://www.facebook.com/blacktrashproductions


More information about the Mercurial-devel mailing list