diff --git a/hgext/narrow/narrowcommands.py b/hgext/narrow/narrowcommands.py --- a/hgext/narrow/narrowcommands.py +++ b/hgext/narrow/narrowcommands.py @@ -290,9 +290,21 @@ with ds.parentchange(): ds.setparents(p1, p2) else: - with wrappedextraprepare,\ - repo.ui.configoverride(overrides, 'widen'): - exchange.pull(repo, remote, heads=common) + with repo.transaction('widening') as tr,\ + remote.commandexecutor() as e: + known = [] + cg = e.callcommand('narrow_widen', { + 'oldincludes': oldincludes, + 'oldexcludes': oldexcludes, + 'newincludes': newincludes, + 'newexcludes': newexcludes, + 'cgversion': '03', + 'common': common, + 'known': known, + }).result() + + with repo.ui.configoverride(overrides, 'widen'): + ret = cg.apply(repo, tr, 'narrow_widen', remote.url()) repo.setnewnarrowpats() actions = {k: [] for k in 'a am f g cd dc r dm dg m e k p pr'.split()} diff --git a/hgext/narrow/narrowwirepeer.py b/hgext/narrow/narrowwirepeer.py --- a/hgext/narrow/narrowwirepeer.py +++ b/hgext/narrow/narrowwirepeer.py @@ -8,14 +8,23 @@ from __future__ import absolute_import from mercurial import ( + changegroup, extensions, hg, + match as matchmod, + narrowspec, + util, wireprotoserver, + wireprototypes, + wireprotov1peer, wireprotov1server, ) +from . import narrowbundle2 + def uisetup(): extensions.wrapfunction(wireprotov1server, '_capabilities', addnarrowcap) + wireprotov1peer.wirepeer.narrow_widen = peernarrowwiden def addnarrowcap(orig, repo, proto): """add the narrow capability to the server""" @@ -37,3 +46,44 @@ return orig(cmd, *args, **kwargs) extensions.wrapfunction(peer, '_calltwowaystream', wrapped) hg.wirepeersetupfuncs.append(wirereposetup) + +@wireprotov1server.wireprotocommand('narrow_widen', '*', permission='pull') +def narrow_widen(repo, proto, args): + """wireprotocol command to send data when a narrow clone is widen. We will + be sending a changegroup here. + + The current set of arguments which are required: + oldincludes: the old includes of the narrow copy + oldexcludes: the old excludes of the narrow copy + newincludes: the new includes of the narrow copy + newexcludes: the new excludes of the narrow copy + common: set of nodes which are common between the server and client + cgversion(maybe): the changegroup version to produce + known: set of nodes which are known on the client (used in ellipses cases) + """ + + oldincludes = wireprototypes.decodelist(args.get('oldincludes')) + newincludes = wireprototypes.decodelist(args.get('newincludes')) + oldexcludes = wireprototypes.decodelist(args.get('oldexcludes')) + newexcludes = wireprototypes.decodelist(args.get('newexcludes')) + common = wireprototypes.decodelist(args.get('common')) + cgversion = args.get('cgversion') + newmatch = narrowspec.match(repo.root, include=newincludes, + exclude=newexcludes) + oldmatch = narrowspec.match(repo.root, include=oldincludes, + exclude=oldexcludes) + diffmatch = matchmod.differencematcher(newmatch, oldmatch) + + # get changegroup data + cg = narrowbundle2.widen_changegroup(repo, diffmatch, common, cgversion) + cg = changegroup.cg3unpacker(util.chunkbuffer(cg), None) + gen = iter(lambda: cg.read(32768), '') + return wireprototypes.streamres(gen=gen) + +def peernarrowwiden(remote, **kwargs): + for ch in ('oldincludes', 'newincludes', 'oldexcludes', 'newexcludes', + 'common', 'known'): + kwargs[ch] = wireprototypes.encodelist(kwargs[ch]) + + f = remote._callcompressable('narrow_widen', **kwargs) + return changegroup.cg3unpacker(f, None) diff --git a/tests/test-narrow-widen-no-ellipsis.t b/tests/test-narrow-widen-no-ellipsis.t --- a/tests/test-narrow-widen-no-ellipsis.t +++ b/tests/test-narrow-widen-no-ellipsis.t @@ -104,23 +104,13 @@ sending batch command searching for changes all local heads known remotely - no changes found - sending getbundle command - bundle2-input-bundle: with-transaction - bundle2-input-part: "changegroup" (params: * mandatory) supported (glob) + sending narrow_widen command adding changesets adding manifests adding widest/ revisions (tree !) adding file changes - adding widest/f revisions (tree !) + adding widest/f revisions added 0 changesets with 1 changes to 1 files - bundle2-input-part: total payload size * (glob) - bundle2-input-part: "listkeys" (params: 1 mandatory) supported - bundle2-input-part: "phase-heads" supported - bundle2-input-part: total payload size 24 - bundle2-input-bundle: 2 parts total - checking for updated bookmarks - 3 local changesets published widest/f: add from widened narrow clone -> g getting widest/f $ hg tracked @@ -143,6 +133,7 @@ adding file changes added 5 changesets with 4 changes to 2 files new changesets *:* (glob) + 3 local changesets published (run 'hg update' to get a working copy) $ hg update -r 'desc("add wider")' 1 files updated, 0 files merged, 0 files removed, 0 files unresolved @@ -179,12 +170,10 @@ $ hg tracked --addinclude wider comparing with ssh://user@dummy/master searching for changes - no changes found adding changesets adding manifests adding file changes added 0 changesets with 1 changes to 1 files - 5 local changesets published $ hg tracked I path:inside I path:wider @@ -284,12 +273,10 @@ $ hg tracked --addinclude d1 comparing with ssh://user@dummy/upstream searching for changes - no changes found adding changesets adding manifests adding file changes added 0 changesets with 1 changes to 1 files - 11 local changesets published $ hg tracked I path:d0 I path:d1 @@ -376,12 +363,10 @@ $ hg --config hooks.pretxnchangegroup.bad=false tracked --addinclude d1 comparing with ssh://user@dummy/upstream searching for changes - no changes found adding changesets adding manifests adding file changes added 0 changesets with 1 changes to 1 files - 11 local changesets published $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n" 11: local 10: add d10/f