[PATCH 1 of 2] discovery: resurrect findoutgoing as findcommonoutgoing for extension hooks

Peter Arrenbrecht peter.arrenbrecht at gmail.com
Fri May 6 08:02:32 CDT 2011


# HG changeset patch
# User Peter Arrenbrecht <peter.arrenbrecht at gmail.com>
# Date 1304685858 -7200
discovery: resurrect findoutgoing as findcommonoutgoing for extension hooks

discovery.findoutgoing used to be a useful hook for extensions like
hgsubversion. This patch reintroduces this version of findcommonincoming
which is meant to be used when computing outgoing changesets.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -702,16 +702,18 @@
             raise util.Abort(_("--base is incompatible with specifying "
                                "a destination"))
         common = [repo.lookup(rev) for rev in base]
+        heads = revs and map(repo.lookup, revs) or revs
     else:
         dest = ui.expandpath(dest or 'default-push', dest or 'default')
         dest, branches = hg.parseurl(dest, opts.get('branch'))
         other = hg.repository(hg.remoteui(repo, opts), dest)
         revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
-        inc = discovery.findcommonincoming(repo, other, force=opts.get('force'))
-        common, _anyinc, _heads = inc
-
-    nodes = revs and map(repo.lookup, revs) or revs
-    cg = repo.getbundle('bundle', common=common, heads=nodes)
+        heads = revs and map(repo.lookup, revs) or revs
+        common, outheads = discovery.findcommonoutgoing(repo, other,
+                                                        onlyheads=heads,
+                                                        force=opts.get('force'))
+
+    cg = repo.getbundle('bundle', common=common, heads=heads)
     if not cg:
         ui.status(_("no changes found\n"))
         return 1
@@ -4025,9 +4027,9 @@
         other = hg.repository(hg.remoteui(repo, {}), dest)
         ui.debug('comparing with %s\n' % util.hidepassword(dest))
         repo.ui.pushbuffer()
-        common, _anyinc, _heads = discovery.findcommonincoming(repo, other)
+        common, outheads = discovery.findcommonoutgoing(repo, other)
         repo.ui.popbuffer()
-        o = repo.changelog.findmissing(common=common)
+        o = repo.changelog.findmissing(common=common, heads=outheads)
         if o:
             t.append(_('%d outgoing') % len(o))
         if 'bookmarks' in other.listkeys('namespaces'):
diff --git a/mercurial/discovery.py b/mercurial/discovery.py
--- a/mercurial/discovery.py
+++ b/mercurial/discovery.py
@@ -23,6 +23,9 @@
 
     If you pass heads and they are all known locally, the reponse lists justs
     these heads in "common" and in "heads".
+
+    Please use findcommonoutgoing to compute the set of outgoing nodes to give
+    extensions a good hook into outgoing.
     """
 
     if not remote.capable('getbundle'):
@@ -43,6 +46,21 @@
     common, anyinc, srvheads = res
     return (list(common), anyinc, heads or list(srvheads))
 
+def findcommonoutgoing(repo, other, onlyheads=None, force=False, commoninc=None):
+    '''Return a tuple (common, anyoutgoing, heads) used to identify the set
+    of nodes present in repo but not in other.
+
+    If onlyheads is given, only nodes ancestral to nodes in onlyheads (inclusive)
+    are included. If you already know the local repo's heads, passing them in
+    onlyheads is faster than letting them be recomputed here.
+
+    If commoninc is given, it must the the result of a prior call to
+    findcommonincoming(repo, other, force) to avoid recomputing it here.
+
+    The returned tuple is meant to be passed to changelog.findmissing.'''
+    common, _any, _hds = commoninc or findcommonincoming(repo, other, force=force)
+    return (common, onlyheads or repo.heads())
+
 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
@@ -57,7 +75,10 @@
     changegroup is a readable file-like object whose read() returns
     successive changegroup chunks ready to be sent over the wire and
     remoteheads is the list of remote heads.'''
-    common, inc, remoteheads = findcommonincoming(repo, remote, force=force)
+    commoninc = findcommonincoming(repo, remote, force=force)
+    common, revs = findcommonoutgoing(repo, remote, onlyheads=revs,
+                                      commoninc=commoninc, force=force)
+    _common, inc, remoteheads = commoninc
 
     cl = repo.changelog
     outg = cl.findmissing(common, revs)
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -480,9 +480,9 @@
         revs = [repo.lookup(rev) for rev in revs]
 
     other = repository(remoteui(repo, opts), dest)
-    inc = discovery.findcommonincoming(repo, other, force=opts.get('force'))
-    common, _anyinc, _heads = inc
-    o = repo.changelog.findmissing(common, revs)
+    common, outheads = discovery.findcommonoutgoing(repo, other, revs,
+                                                    force=opts.get('force'))
+    o = repo.changelog.findmissing(common, outheads)
     if not o:
         ui.status(_("no changes found\n"))
         return None
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -558,10 +558,10 @@
         revs = [repo.lookup(rev) for rev in revs]
     other = hg.repository(hg.remoteui(repo, {}), dest)
     repo.ui.pushbuffer()
-    common, _anyinc, _heads = discovery.findcommonincoming(repo, other)
+    common, outheads = discovery.findcommonoutgoing(repo, other, onlyheads=revs)
     repo.ui.popbuffer()
     cl = repo.changelog
-    o = set([cl.rev(r) for r in repo.changelog.findmissing(common, revs)])
+    o = set([cl.rev(r) for r in repo.changelog.findmissing(common, outheads)])
     return [r for r in subset if r in o]
 
 def p1(repo, subset, x):


More information about the Mercurial-devel mailing list