--- a/hgext3rd/evolve/__init__.py Tue Feb 28 16:12:34 2017 +0100
+++ b/hgext3rd/evolve/__init__.py Tue Feb 28 18:21:23 2017 +0100
@@ -123,6 +123,10 @@
from mercurial.i18n import _
from mercurial.node import nullid
+from . import serveronly
+
+obsexcmsg = serveronly.obsexcmsg
+
cmdtable = {}
command = cmdutil.command(cmdtable)
@@ -387,6 +391,8 @@
extsetup = eh.final_extsetup
reposetup = eh.final_reposetup
+eh.extsetup(serveronly.extsetup)
+
#####################################################################
### Option configuration ###
#####################################################################
@@ -3307,14 +3313,6 @@
### Obsolescence marker exchange experimenation ###
#####################################################################
-def obsexcmsg(ui, message, important=False):
- verbose = ui.configbool('experimental', 'verbose-obsolescence-exchange',
- False)
- if verbose:
- message = 'OBSEXC: ' + message
- if important or verbose:
- ui.status(message)
-
def obsexcprg(ui, *args, **kwargs):
topic = 'obsmarkers exchange'
if ui.configbool('experimental', 'verbose-obsolescence-exchange', False):
@@ -3362,65 +3360,25 @@
obsexcmsg(repo.ui, "markers already in sync\n")
pushop.outobsmarkers = []
-@eh.wrapfunction(wireproto, 'capabilities')
-def discocapabilities(orig, repo, proto):
- """wrapper to advertise new capability"""
- caps = orig(repo, proto)
- if obsolete.isenabled(repo, obsolete.exchangeopt):
- caps += ' _evoext_obshash_0'
- return caps
-
@eh.extsetup
def _installobsmarkersdiscovery(ui):
- hgweb_mod.perms['evoext_obshash'] = 'pull'
- hgweb_mod.perms['evoext_obshash1'] = 'pull'
- # wrap command content
- oldcap, args = wireproto.commands['capabilities']
- def newcap(repo, proto):
- return discocapabilities(oldcap, repo, proto)
- wireproto.commands['capabilities'] = (newcap, args)
- wireproto.commands['evoext_obshash'] = (srv_obshash, 'nodes')
- wireproto.commands['evoext_obshash1'] = (srv_obshash1, 'nodes')
- if getattr(exchange, '_pushdiscoveryobsmarkers', None) is None:
- ui.warn(_('evolve: your mercurial version is too old\n'
- 'evolve: (running in degraded mode, push will '
- 'includes all markers)\n'))
- else:
- olddisco = exchange.pushdiscoverymapping['obsmarker']
- def newdisco(pushop):
- _pushdiscoveryobsmarkers(olddisco, pushop)
- exchange.pushdiscoverymapping['obsmarker'] = newdisco
+ olddisco = exchange.pushdiscoverymapping['obsmarker']
+ def newdisco(pushop):
+ _pushdiscoveryobsmarkers(olddisco, pushop)
+ exchange.pushdiscoverymapping['obsmarker'] = newdisco
### Set discovery START
from mercurial import dagutil
from mercurial import setdiscovery
-def _obshash(repo, nodes, version=0):
- if version == 0:
- hashs = _obsrelsethashtreefm0(repo)
- elif version ==1:
- hashs = _obsrelsethashtreefm1(repo)
- else:
- assert False
- nm = repo.changelog.nodemap
- revs = [nm.get(n) for n in nodes]
- return [r is None and nullid or hashs[r][1] for r in revs]
-
-def srv_obshash(repo, proto, nodes):
- return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes)))
-
-def srv_obshash1(repo, proto, nodes):
- return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes),
- version=1))
-
@eh.addattr(localrepo.localpeer, 'evoext_obshash')
def local_obshash(peer, nodes):
- return _obshash(peer._repo, nodes)
+ return serveronly._obshash(peer._repo, nodes)
@eh.addattr(localrepo.localpeer, 'evoext_obshash1')
def local_obshash1(peer, nodes):
- return _obshash(peer._repo, nodes, version=1)
+ return serveronly._obshash(peer._repo, nodes, version=1)
@eh.addattr(wireproto.wirepeer, 'evoext_obshash')
def peer_obshash(self, nodes):
@@ -3453,10 +3411,10 @@
_takefullsample = setdiscovery._takefullsample
if remote.capable('_evoext_obshash_1'):
getremotehash = remote.evoext_obshash1
- localhash = _obsrelsethashtreefm1(local)
+ localhash = serveronly._obsrelsethashtreefm1(local)
else:
getremotehash = remote.evoext_obshash
- localhash = _obsrelsethashtreefm0(local)
+ localhash = serveronly._obsrelsethashtreefm0(local)
while undecided:
@@ -3605,33 +3563,10 @@
caps.add('_evoext_pushobsmarkers_0')
return caps
-def _pushobsmarkers(repo, data):
- tr = lock = None
- try:
- lock = repo.lock()
- tr = repo.transaction('pushkey: obsolete markers')
- new = repo.obsstore.mergemarkers(tr, data)
- if new is not None:
- obsexcmsg(repo.ui, "%i obsolescence markers added\n" % new, True)
- tr.close()
- finally:
- lockmod.release(tr, lock)
- repo.hook('evolve_pushobsmarkers')
-
@eh.addattr(localrepo.localpeer, 'evoext_pushobsmarkers_0')
def local_pushobsmarkers(peer, obsfile):
data = obsfile.read()
- _pushobsmarkers(peer._repo, data)
-
-def srv_pushobsmarkers(repo, proto):
- """wireprotocol command"""
- fp = StringIO()
- proto.redirect()
- proto.getfile(fp)
- data = fp.getvalue()
- fp.close()
- _pushobsmarkers(repo, data)
- return wireproto.pushres(0)
+ serveronly._pushobsmarkers(peer._repo, data)
def _buildpullobsmarkersboundaries(pullop):
"""small funtion returning the argument for pull markers call
@@ -3664,29 +3599,6 @@
kwargs['evo_obscommon'] = common
return ret
-@eh.wrapfunction(exchange, '_getbundleobsmarkerpart')
-def _getbundleobsmarkerpart(orig, bundler, repo, source, **kwargs):
- if 'evo_obscommon' not in kwargs:
- return orig(bundler, repo, source, **kwargs)
-
- heads = kwargs.get('heads')
- if kwargs.get('obsmarkers', False):
- if heads is None:
- heads = repo.heads()
- obscommon = kwargs.get('evo_obscommon', ())
- assert obscommon
- obsset = repo.unfiltered().set('::%ln - ::%ln', heads, obscommon)
- subset = [c.node() for c in obsset]
- markers = repo.obsstore.relevantmarkers(subset)
- exchange.buildobsmarkerspart(bundler, markers)
-
-@eh.uisetup
-def installgetbundlepartgen(ui):
- origfunc = exchange.getbundle2partsmapping['obsmarkers']
- def newfunc(*args, **kwargs):
- return _getbundleobsmarkerpart(origfunc, *args, **kwargs)
- exchange.getbundle2partsmapping['obsmarkers'] = newfunc
-
@eh.wrapfunction(exchange, '_pullobsolete')
def _pullobsolete(orig, pullop):
if not obsolete.isenabled(pullop.repo, obsolete.exchangeopt):
@@ -3728,28 +3640,6 @@
pullop.repo.invalidatevolatilesets()
return tr
-def _getobsmarkersstream(repo, heads=None, common=None):
- revset = ''
- args = []
- repo = repo.unfiltered()
- if heads is None:
- revset = 'all()'
- elif heads:
- revset += "(::%ln)"
- args.append(heads)
- else:
- assert False, 'pulling no heads?'
- if common:
- revset += ' - (::%ln)'
- args.append(common)
- nodes = [c.node() for c in repo.set(revset, *args)]
- markers = repo.obsstore.relevantmarkers(nodes)
- obsdata = StringIO()
- for chunk in obsolete.encodemarkers(markers, True):
- obsdata.write(chunk)
- obsdata.seek(0)
- return obsdata
-
@eh.addattr(wireproto.wirepeer, 'evoext_pullobsmarkers_0')
def client_pullobsmarkers(self, heads=None, common=None):
self.requirecap('_evoext_pullobsmarkers_0', _('look up remote obsmarkers'))
@@ -3776,75 +3666,8 @@
@eh.addattr(localrepo.localpeer, 'evoext_pullobsmarkers_0')
def local_pullobsmarkers(self, heads=None, common=None):
- return _getobsmarkersstream(self._repo, heads=heads, common=common)
-
-# The wireproto.streamres API changed, handling chunking and compression
-# directly. Handle either case.
-if util.safehasattr(wireproto.abstractserverproto, 'groupchunks'):
- # We need to handle chunking and compression directly
- def streamres(d, proto):
- return wireproto.streamres(proto.groupchunks(d))
-else:
- # Leave chunking and compression to streamres
- def streamres(d, proto):
- return wireproto.streamres(reader=d, v1compressible=True)
-
-def srv_pullobsmarkers(repo, proto, others):
- opts = wireproto.options('', ['heads', 'common'], others)
- for k, v in opts.iteritems():
- if k in ('heads', 'common'):
- opts[k] = wireproto.decodelist(v)
- obsdata = _getobsmarkersstream(repo, **opts)
- finaldata = StringIO()
- obsdata = obsdata.getvalue()
- finaldata.write('%20i' % len(obsdata))
- finaldata.write(obsdata)
- finaldata.seek(0)
- return streamres(finaldata, proto)
-
-def _obsrelsethashtreefm0(repo):
- return _obsrelsethashtree(repo, obsolete._fm0encodeonemarker)
-
-def _obsrelsethashtreefm1(repo):
- return _obsrelsethashtree(repo, obsolete._fm1encodeonemarker)
-
-def _obsrelsethashtree(repo, encodeonemarker):
- cache = []
- unfi = repo.unfiltered()
- markercache = {}
- repo.ui.progress(_("preparing locally"), 0, total=len(unfi))
- for i in unfi:
- ctx = unfi[i]
- entry = 0
- sha = hashlib.sha1()
- # add data from p1
- for p in ctx.parents():
- p = p.rev()
- if p < 0:
- p = nullid
- else:
- p = cache[p][1]
- if p != nullid:
- entry += 1
- sha.update(p)
- tmarkers = repo.obsstore.relevantmarkers([ctx.node()])
- if tmarkers:
- bmarkers = []
- for m in tmarkers:
- if not m in markercache:
- markercache[m] = encodeonemarker(m)
- bmarkers.append(markercache[m])
- bmarkers.sort()
- for m in bmarkers:
- entry += 1
- sha.update(m)
- if entry:
- cache.append((ctx.node(), sha.digest()))
- else:
- cache.append((ctx.node(), nullid))
- repo.ui.progress(_("preparing locally"), i, total=len(unfi))
- repo.ui.progress(_("preparing locally"), None)
- return cache
+ return serveronly._getobsmarkersstream(self._repo, heads=heads,
+ common=common)
@command('debugobsrelsethashtree',
[('', 'v0', None, 'hash on marker format "0"'),
@@ -3858,9 +3681,9 @@
if v0 and v1:
raise error.Abort('cannot only specify one format')
elif v0:
- treefunc = _obsrelsethashtreefm0
+ treefunc = serveronly._obsrelsethashtreefm0
else:
- treefunc = _obsrelsethashtreefm1
+ treefunc = serveronly._obsrelsethashtreefm1
for chg, obs in treefunc(repo):
ui.status('%s %s\n' % (node.hex(chg), node.hex(obs)))
@@ -3912,32 +3735,6 @@
ui.write(_('Done!\n'))
-@eh.wrapfunction(wireproto, 'capabilities')
-def capabilities(orig, repo, proto):
- """wrapper to advertise new capability"""
- caps = orig(repo, proto)
- if obsolete.isenabled(repo, obsolete.exchangeopt):
- caps += ' _evoext_pushobsmarkers_0'
- caps += ' _evoext_pullobsmarkers_0'
- caps += ' _evoext_obshash_0'
- caps += ' _evoext_obshash_1'
- caps += ' _evoext_getbundle_obscommon'
- return caps
-
-
-@eh.extsetup
-def _installwireprotocol(ui):
- localrepo.moderncaps.add('_evoext_pullobsmarkers_0')
- hgweb_mod.perms['evoext_pushobsmarkers_0'] = 'push'
- hgweb_mod.perms['evoext_pullobsmarkers_0'] = 'pull'
- wireproto.commands['evoext_pushobsmarkers_0'] = (srv_pushobsmarkers, '')
- wireproto.commands['evoext_pullobsmarkers_0'] = (srv_pullobsmarkers, '*')
- # wrap command content
- oldcap, args = wireproto.commands['capabilities']
- def newcap(repo, proto):
- return capabilities(oldcap, repo, proto)
- wireproto.commands['capabilities'] = (newcap, args)
-
def _helploader(ui):
return help.gettext(evolutionhelptext)
--- a/hgext3rd/evolve/serveronly.py Tue Feb 28 16:12:34 2017 +0100
+++ b/hgext3rd/evolve/serveronly.py Tue Feb 28 18:21:23 2017 +0100
@@ -21,12 +21,14 @@
exchange,
extensions,
localrepo,
+ lock as lockmod,
node,
obsolete,
util,
wireproto
)
from mercurial.hgweb import hgweb_mod
+from mercurial.i18n import _
_pack = struct.pack
gboptslist = gboptsmap = None
@@ -51,29 +53,37 @@
# End of simple4server specific content
+def obsexcmsg(ui, message, important=False):
+ verbose = ui.configbool('experimental', 'verbose-obsolescence-exchange',
+ False)
+ if verbose:
+ message = 'OBSEXC: ' + message
+ if important or verbose:
+ ui.status(message)
-# from evolve extension: 1a23c7c52a43
+def _pushobsmarkers(repo, data):
+ tr = lock = None
+ try:
+ lock = repo.lock()
+ tr = repo.transaction('pushkey: obsolete markers')
+ new = repo.obsstore.mergemarkers(tr, data)
+ if new is not None:
+ obsexcmsg(repo.ui, "%i obsolescence markers added\n" % new, True)
+ tr.close()
+ finally:
+ lockmod.release(tr, lock)
+ repo.hook('evolve_pushobsmarkers')
+
def srv_pushobsmarkers(repo, proto):
- """That receives a stream of markers and apply then to the repo"""
+ """wireprotocol command"""
fp = StringIO()
proto.redirect()
proto.getfile(fp)
data = fp.getvalue()
fp.close()
- lock = repo.lock()
- try:
- tr = repo.transaction('pushkey: obsolete markers')
- try:
- repo.obsstore.mergemarkers(tr, data)
- tr.close()
- finally:
- tr.release()
- finally:
- lock.release()
- repo.hook('evolve_pushobsmarkers')
+ _pushobsmarkers(repo, data)
return wireproto.pushres(0)
-# from evolve extension: 1a23c7c52a43
def _getobsmarkersstream(repo, heads=None, common=None):
"""Get a binary stream for all markers relevant to `::<heads> - ::<common>`
"""
@@ -98,64 +108,6 @@
obsdata.seek(0)
return obsdata
-if not util.safehasattr(obsolete.obsstore, 'relevantmarkers'):
- # from evolve extension: 1a23c7c52a43
- class pruneobsstore(obsolete.obsstore):
- """And extended obsstore class that read parent information from v1
- format
-
- Evolve extension adds parent information in prune marker.
- We use it to make markers relevant to pushed changeset."""
-
- def __init__(self, *args, **kwargs):
- self.prunedchildren = {}
- return super(pruneobsstore, self).__init__(*args, **kwargs)
-
- def _load(self, markers):
- markers = self._prunedetectingmarkers(markers)
- return super(pruneobsstore, self)._load(markers)
-
-
- def _prunedetectingmarkers(self, markers):
- for m in markers:
- if not m[1]: # no successors
- meta = obsolete.decodemeta(m[3])
- if 'p1' in meta:
- p1 = node.bin(meta['p1'])
- self.prunedchildren.setdefault(p1, set()).add(m)
- if 'p2' in meta:
- p2 = node.bin(meta['p2'])
- self.prunedchildren.setdefault(p2, set()).add(m)
- yield m
-
- # from evolve extension: 1a23c7c52a43
- def relevantmarkers(self, nodes):
- """return a set of all obsolescence marker relevant to a set of node.
-
- "relevant" to a set of node mean:
-
- - marker that use this changeset as successors
- - prune marker of direct children on this changeset.
- - recursive application of the two rules on precursors of these markers
-
- It is a set so you cannot rely on order"""
- seennodes = set(nodes)
- seenmarkers = set()
- pendingnodes = set(nodes)
- precursorsmarkers = self.precursors
- prunedchildren = self.prunedchildren
- while pendingnodes:
- direct = set()
- for current in pendingnodes:
- direct.update(precursorsmarkers.get(current, ()))
- direct.update(prunedchildren.get(current, ()))
- direct -= seenmarkers
- pendingnodes = set([m[0] for m in direct])
- seenmarkers |= direct
- pendingnodes -= seennodes
- seennodes |= pendingnodes
- return seenmarkers
-
# The wireproto.streamres API changed, handling chunking and compression
# directly. Handle either case.
if util.safehasattr(wireproto.abstractserverproto, 'groupchunks'):
@@ -167,7 +119,6 @@
def streamres(d, proto):
return wireproto.streamres(reader=d, v1compressible=True)
-# from evolve extension: cf35f38d6a10
def srv_pullobsmarkers(repo, proto, others):
"""serves a binary stream of markers.
@@ -186,20 +137,17 @@
finaldata.seek(0)
return streamres(finaldata, proto)
-
-# from evolve extension: 3249814dabd1
def _obsrelsethashtreefm0(repo):
return _obsrelsethashtree(repo, obsolete._fm0encodeonemarker)
-# from evolve extension: 3249814dabd1
def _obsrelsethashtreefm1(repo):
return _obsrelsethashtree(repo, obsolete._fm1encodeonemarker)
-# from evolve extension: 3249814dabd1
def _obsrelsethashtree(repo, encodeonemarker):
cache = []
unfi = repo.unfiltered()
markercache = {}
+ repo.ui.progress(_("preparing locally"), 0, total=len(unfi))
for i in unfi:
ctx = unfi[i]
entry = 0
@@ -229,9 +177,10 @@
cache.append((ctx.node(), sha.digest()))
else:
cache.append((ctx.node(), node.nullid))
+ repo.ui.progress(_("preparing locally"), i, total=len(unfi))
+ repo.ui.progress(_("preparing locally"), None)
return cache
-# from evolve extension: 3249814dabd1
def _obshash(repo, nodes, version=0):
if version == 0:
hashs = _obsrelsethashtreefm0(repo)
@@ -241,18 +190,15 @@
assert False
nm = repo.changelog.nodemap
revs = [nm.get(n) for n in nodes]
- return [r is None and node.nullid or hashs[r][1] for r in revs]
+ return [r is None and nullid or hashs[r][1] for r in revs]
-# from evolve extension: 3249814dabd1
def srv_obshash(repo, proto, nodes):
return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes)))
-# from evolve extension: 3249814dabd1
def srv_obshash1(repo, proto, nodes):
return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes),
version=1))
-# from evolve extension: 3249814dabd1
def capabilities(orig, repo, proto):
"""wrapper to advertise new capability"""
caps = orig(repo, proto)
@@ -270,29 +216,23 @@
return orig(bundler, repo, source, **kwargs)
heads = kwargs.get('heads')
- if 'evo_obscommon' not in kwargs:
- return orig(bundler, repo, source, **kwargs)
-
if kwargs.get('obsmarkers', False):
if heads is None:
heads = repo.heads()
obscommon = kwargs.get('evo_obscommon', ())
- obsset = repo.set('::%ln - ::%ln', heads, obscommon)
+ assert obscommon
+ obsset = repo.unfiltered().set('::%ln - ::%ln', heads, obscommon)
subset = [c.node() for c in obsset]
markers = repo.obsstore.relevantmarkers(subset)
exchange.buildobsmarkerspart(bundler, markers)
-# from evolve extension: 10867a8e27c6
-# heavily modified
def extsetup(ui):
localrepo.moderncaps.add('_evoext_b2x_obsmarkers_0')
gboptsmap['evo_obscommon'] = 'nodes'
- if not util.safehasattr(obsolete.obsstore, 'relevantmarkers'):
- obsolete.obsstore = pruneobsstore
- obsolete.obsstore.relevantmarkers = relevantmarkers
hgweb_mod.perms['evoext_pushobsmarkers_0'] = 'push'
hgweb_mod.perms['evoext_pullobsmarkers_0'] = 'pull'
hgweb_mod.perms['evoext_obshash'] = 'pull'
+ hgweb_mod.perms['evoext_obshash1'] = 'pull'
wireproto.commands['evoext_pushobsmarkers_0'] = (srv_pushobsmarkers, '')
wireproto.commands['evoext_pullobsmarkers_0'] = (srv_pullobsmarkers, '*')
# wrap module content