##// END OF EJS Templates
hg-cpython: use ancestor iterator impls from vcsgraph...
hg-cpython: use ancestor iterator impls from vcsgraph Differential Revision: https://phab.mercurial-scm.org/D11947

File last commit:

r47758:07b9ebea default
r49350:35ebe6f8 default
Show More
treediscovery.py
187 lines | 5.9 KiB | text/x-python | PythonLexer
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 # discovery.py - protocol changeset discovery functions
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2010 Olivia Mackall <olivia@selenic.com>
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 #
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Gregory Szorc
treediscovery: use absolute_import
r25987 from __future__ import absolute_import
Martin von Zweigbergk
util: drop alias for collections.deque...
r25113 import collections
Gregory Szorc
treediscovery: use absolute_import
r25987
from .i18n import _
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 from .node import short
Gregory Szorc
treediscovery: use absolute_import
r25987 from . import (
error,
Gregory Szorc
global: use pycompat.xrange()...
r38806 pycompat,
Gregory Szorc
treediscovery: use absolute_import
r25987 )
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
Augie Fackler
formatting: blacken the codebase...
r43346
debugdiscovery: display the number of roundtrip used...
r46726 def findcommonincoming(repo, remote, heads=None, force=False, audit=None):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 """Return a tuple (common, fetch, heads) used to identify the common
subset of nodes between repo and remote.
"common" is a list of (at least) the heads of the common subset.
"fetch" is a list of roots of the nodes that would be incoming, to be
supplied to changegroupsubset.
"heads" is either the supplied heads, or else the remote's heads.
"""
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 knownnode = repo.changelog.hasnode
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 search = []
fetch = set()
seen = set()
seenbranch = set()
base = set()
if not heads:
Gregory Szorc
treediscovery: switch to command executor interface...
r37652 with remote.commandexecutor() as e:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 heads = e.callcommand(b'heads', {}).result()
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
debugdiscovery: display the number of roundtrip used...
r46726 if audit is not None:
audit[b'total-roundtrips'] = 1
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 if repo.changelog.tip() == repo.nullid:
base.add(repo.nullid)
if heads != [repo.nullid]:
return [repo.nullid], [repo.nullid], list(heads)
return [repo.nullid], [], heads
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
# assume we're closer to the tip than the root
# and start by examining the heads
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.status(_(b"searching for changes\n"))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
unknown = []
for h in heads:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if not knownnode(h):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 unknown.append(h)
else:
base.add(h)
Peter Arrenbrecht
treediscovery: fix regression when run against older repos (issue2793)...
r14199 if not unknown:
return list(base), [], list(heads)
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 req = set(unknown)
reqcnt = 0
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 progress = repo.ui.makeprogress(_(b'searching'), unit=_(b'queries'))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
# search through remote branches
# a 'branch' here is a linear segment of history, with four parts:
# head, root, first parent, second parent
# (a branch always has two parents (or none) by definition)
Gregory Szorc
treediscovery: switch to command executor interface...
r37652 with remote.commandexecutor() as e:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 branches = e.callcommand(b'branches', {b'nodes': unknown}).result()
Gregory Szorc
treediscovery: switch to command executor interface...
r37652
unknown = collections.deque(branches)
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 while unknown:
r = []
while unknown:
Bryan O'Sullivan
cleanup: use the deque type where appropriate...
r16803 n = unknown.popleft()
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 if n[0] in seen:
continue
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"examining %s:%s\n" % (short(n[0]), short(n[1])))
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 if n[0] == repo.nullid: # found the end of the branch
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 pass
elif n in seenbranch:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"branch already found\n")
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 continue
Augie Fackler
formatting: blacken the codebase...
r43346 elif n[1] and knownnode(n[1]): # do we know the base?
repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"found incomplete branch %s:%s\n"
Augie Fackler
formatting: blacken the codebase...
r43346 % (short(n[0]), short(n[1]))
)
search.append(n[0:2]) # schedule branch range for scanning
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 seenbranch.add(n)
else:
if n[1] not in seen and n[1] not in fetch:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if knownnode(n[2]) and knownnode(n[3]):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"found new changeset %s\n" % short(n[1]))
Augie Fackler
formatting: blacken the codebase...
r43346 fetch.add(n[1]) # earliest unknown
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 for p in n[2:4]:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if knownnode(p):
Augie Fackler
formatting: blacken the codebase...
r43346 base.add(p) # latest known
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
for p in n[2:4]:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if p not in req and not knownnode(p):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 r.append(p)
req.add(p)
seen.add(n[0])
if r:
reqcnt += 1
Martin von Zweigbergk
treediscovery: use progress helper...
r38419 progress.increment()
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"request %d: %s\n" % (reqcnt, b" ".join(map(short, r)))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
global: use pycompat.xrange()...
r38806 for p in pycompat.xrange(0, len(r), 10):
Gregory Szorc
treediscovery: switch to command executor interface...
r37652 with remote.commandexecutor() as e:
Augie Fackler
formatting: blacken the codebase...
r43346 branches = e.callcommand(
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 b'branches',
{
b'nodes': r[p : p + 10],
},
Augie Fackler
formatting: blacken the codebase...
r43346 ).result()
Gregory Szorc
treediscovery: switch to command executor interface...
r37652
for b in branches:
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"received %s:%s\n" % (short(b[0]), short(b[1]))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 unknown.append(b)
# do binary search on the branches we found
while search:
newsearch = []
reqcnt += 1
Martin von Zweigbergk
treediscovery: use progress helper...
r38419 progress.increment()
Gregory Szorc
treediscovery: switch to command executor interface...
r37652
with remote.commandexecutor() as e:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 between = e.callcommand(b'between', {b'pairs': search}).result()
Gregory Szorc
treediscovery: switch to command executor interface...
r37652
for n, l in zip(search, between):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 l.append(n[1])
p = n[0]
f = 1
for i in l:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"narrowing %d:%d %s\n" % (f, len(l), short(i)))
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if knownnode(i):
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 if f <= 2:
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"found new branch changeset %s\n" % short(p)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 fetch.add(p)
base.add(i)
else:
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"narrowed branch search to %s:%s\n"
Augie Fackler
formatting: blacken the codebase...
r43346 % (short(p), short(i))
)
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 newsearch.append((p, i))
break
p, f = i, f * 2
search = newsearch
# sanity check our fetch list
for f in fetch:
Pierre-Yves David
discovery: stop using nodemap for membership testing...
r20225 if knownnode(f):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.RepoError(_(b"already have changeset ") + short(f[:4]))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
base = list(base)
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 if base == [repo.nullid]:
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 if force:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.warn(_(b"warning: repository is unrelated\n"))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"repository is unrelated"))
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"found new changesets starting at "
+ b" ".join([short(f) for f in fetch])
+ b"\n"
Augie Fackler
formatting: blacken the codebase...
r43346 )
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
Martin von Zweigbergk
treediscovery: use progress helper...
r38419 progress.complete()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"%d total queries\n" % reqcnt)
debugdiscovery: display the number of roundtrip used...
r46726 if audit is not None:
audit[b'total-roundtrips'] = reqcnt
Peter Arrenbrecht
discovery: add new set-based discovery...
r14164
return base, list(fetch), heads