diff --git a/hgext/narrow/narrowbundle2.py b/hgext/narrow/narrowbundle2.py --- a/hgext/narrow/narrowbundle2.py +++ b/hgext/narrow/narrowbundle2.py @@ -50,6 +50,50 @@ caps[NARROWCAP] = ['v0'] return caps +def getbundlechangegrouppart_nonellipsis(bundler, repo, source, bundlecaps=None, + b2caps=None, heads=None, common=None, + **kwargs): + """Handling changegroup changegroup generation on the server when user + is widening their narrowspec""" + + cgversions = b2caps.get('changegroup') + if cgversions: # 3.1 and 3.2 ship with an empty value + cgversions = [v for v in cgversions + if v in changegroup.supportedoutgoingversions(repo)] + if not cgversions: + raise ValueError(_('no common changegroup version')) + version = max(cgversions) + else: + raise ValueError(_("server does not advertise changegroup version," + " can't negotiate support for ellipsis nodes")) + + include = sorted(filter(bool, kwargs.get(r'includepats', []))) + exclude = sorted(filter(bool, kwargs.get(r'excludepats', []))) + newmatch = narrowspec.match(repo.root, include=include, exclude=exclude) + oldinclude = sorted(filter(bool, kwargs.get(r'oldincludepats', []))) + oldexclude = sorted(filter(bool, kwargs.get(r'oldexcludepats', []))) + common = set(common or [nullid]) + + if (oldinclude != include or oldexclude != exclude): + common = repo.revs("::%ln", common) + commonnodes = set() + cl = repo.changelog + for c in common: + commonnodes.add(cl.node(c)) + if commonnodes: + # XXX: we should only send the filelogs (and treemanifest). user + # already has the changelog and manifest + packer = changegroup.getbundler(version, repo, + filematcher=newmatch, + fullnodes=commonnodes) + cgdata = packer.generate(set([nullid]), list(commonnodes), False, + source) + + part = bundler.newpart('changegroup', data=cgdata) + part.addparam('version', version) + if 'treemanifest' in repo.requirements: + part.addparam('treemanifest', '1') + # Serve a changegroup for a client with a narrow clone. def getbundlechangegrouppart_narrow(bundler, repo, source, bundlecaps=None, b2caps=None, heads=None, @@ -254,6 +298,7 @@ getbundleargs = wireprototypes.GETBUNDLE_ARGUMENTS getbundleargs['narrow'] = 'boolean' + getbundleargs['widen'] = 'boolean' getbundleargs['depth'] = 'plain' getbundleargs['oldincludepats'] = 'csv' getbundleargs['oldexcludepats'] = 'csv' @@ -271,6 +316,8 @@ if (kwargs.get(r'narrow', False) and repo.ui.configbool('experimental', 'narrowservebrokenellipses')): getbundlechangegrouppart_narrow(*args, **kwargs) + elif kwargs.get(r'widen', False) and kwargs.get(r'narrow', False): + getbundlechangegrouppart_nonellipsis(*args, **kwargs) else: origcgfn(*args, **kwargs) exchange.getbundle2partsmapping['changegroup'] = wrappedcgfn diff --git a/hgext/narrow/narrowcommands.py b/hgext/narrow/narrowcommands.py --- a/hgext/narrow/narrowcommands.py +++ b/hgext/narrow/narrowcommands.py @@ -286,6 +286,7 @@ # The old{in,ex}cludepats have already been set by orig() kwargs['includepats'] = newincludes kwargs['excludepats'] = newexcludes + kwargs['widen'] = True wrappedextraprepare = extensions.wrappedfunction(exchange, '_pullbundle2extraprepare', pullbundle2extraprepare_widen) diff --git a/tests/test-narrow-widen-non-ellipsis.t b/tests/test-narrow-widen-non-ellipsis.t --- a/tests/test-narrow-widen-non-ellipsis.t +++ b/tests/test-narrow-widen-non-ellipsis.t @@ -89,6 +89,10 @@ comparing with ssh://user@dummy/master searching for changes no changes found + adding changesets + adding manifests + adding file changes + added 0 changesets with 0 changes to 1 files 3 local changesets published $ hg tracked I path:inside @@ -141,6 +145,10 @@ comparing with ssh://user@dummy/master searching for changes no changes found + adding changesets + adding manifests + adding file changes + added 0 changesets with 4 changes to 2 files 5 local changesets published abort: path ends in directory separator: widest/ [255] @@ -247,6 +255,10 @@ 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 5 files 11 local changesets published abort: path ends in directory separator: d1/ [255] @@ -274,9 +286,12 @@ checking changesets checking manifests checking directory manifests + warning: orphan data file 'meta/d1/00manifest.i' crosschecking files in changesets and manifests checking files + warning: orphan data file 'data/d1/f.i' 4 files, 11 changesets, 4 total revisions + 2 warnings encountered! Widening preserves parent of local commit @@ -340,6 +355,10 @@ 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 2 files 11 local changesets published abort: path ends in directory separator: d1/ [255]