discovery: resurrect findoutgoing as findcommonoutgoing for extension hooks
authorPeter Arrenbrecht <peter.arrenbrecht@gmail.com>
Fri, 06 May 2011 14:44:18 +0200
changeset 14213 30273f0c776b
parent 14212 8f551386abf0
child 14214 c5db85676c38
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.
mercurial/commands.py
mercurial/discovery.py
mercurial/hg.py
mercurial/revset.py
--- a/mercurial/commands.py	Fri May 06 16:00:48 2011 +0300
+++ b/mercurial/commands.py	Fri May 06 14:44:18 2011 +0200
@@ -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
@@ -4024,9 +4026,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'):
--- a/mercurial/discovery.py	Fri May 06 16:00:48 2011 +0300
+++ b/mercurial/discovery.py	Fri May 06 14:44:18 2011 +0200
@@ -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)
--- a/mercurial/hg.py	Fri May 06 16:00:48 2011 +0300
+++ b/mercurial/hg.py	Fri May 06 14:44:18 2011 +0200
@@ -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
--- a/mercurial/revset.py	Fri May 06 16:00:48 2011 +0300
+++ b/mercurial/revset.py	Fri May 06 14:44:18 2011 +0200
@@ -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):