comparison mercurial/changegroup.py @ 38794:1d01cf0416a5

changegroup: move file matcher from narrow extension Sparse changegroup generation requires the use of a matcher to filter which files are relevant. This commit moves the file matcher from the narrow extension to core and updates the narrow extension to use it. I'm not sure why the narrow extension was storing the matcher as a callable that resolved to a matcher. So I changed it to be a simple matcher instance. In addition, code from narrow to intersect the matcher with the local narrow spec is now performed automatically when the changegroup packer is created. If a matcher is not passed into getbundler() an alwaysmatcher() is assumed. This ensures that a matcher is always defined for all operations. Differential Revision: https://phab.mercurial-scm.org/D4011
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 28 Jul 2018 11:40:31 -0700
parents e7aa113b14f7
children 5742d0428ed9
comparison
equal deleted inserted replaced
38793:6c8e3c847977 38794:1d01cf0416a5
19 ) 19 )
20 20
21 from . import ( 21 from . import (
22 dagutil, 22 dagutil,
23 error, 23 error,
24 match as matchmod,
24 mdiff, 25 mdiff,
25 phases, 26 phases,
26 pycompat, 27 pycompat,
27 util, 28 util,
28 ) 29 )
494 return readexactly(self._fh, n) 495 return readexactly(self._fh, n)
495 496
496 class cg1packer(object): 497 class cg1packer(object):
497 deltaheader = _CHANGEGROUPV1_DELTA_HEADER 498 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
498 version = '01' 499 version = '01'
499 def __init__(self, repo, bundlecaps=None): 500 def __init__(self, repo, filematcher, bundlecaps=None):
500 """Given a source repo, construct a bundler. 501 """Given a source repo, construct a bundler.
502
503 filematcher is a matcher that matches on files to include in the
504 changegroup. Used to facilitate sparse changegroups.
501 505
502 bundlecaps is optional and can be used to specify the set of 506 bundlecaps is optional and can be used to specify the set of
503 capabilities which can be used to build the bundle. While bundlecaps is 507 capabilities which can be used to build the bundle. While bundlecaps is
504 unused in core Mercurial, extensions rely on this feature to communicate 508 unused in core Mercurial, extensions rely on this feature to communicate
505 capabilities to customize the changegroup packer. 509 capabilities to customize the changegroup packer.
506 """ 510 """
511 assert filematcher
512 self._filematcher = filematcher
513
507 # Set of capabilities we can use to build the bundle. 514 # Set of capabilities we can use to build the bundle.
508 if bundlecaps is None: 515 if bundlecaps is None:
509 bundlecaps = set() 516 bundlecaps = set()
510 self._bundlecaps = bundlecaps 517 self._bundlecaps = bundlecaps
511 # experimental config: bundle.reorder 518 # experimental config: bundle.reorder
811 818
812 class cg2packer(cg1packer): 819 class cg2packer(cg1packer):
813 version = '02' 820 version = '02'
814 deltaheader = _CHANGEGROUPV2_DELTA_HEADER 821 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
815 822
816 def __init__(self, repo, bundlecaps=None): 823 def __init__(self, repo, filematcher, bundlecaps=None):
817 super(cg2packer, self).__init__(repo, bundlecaps) 824 super(cg2packer, self).__init__(repo, filematcher,
825 bundlecaps=bundlecaps)
826
818 if self._reorder is None: 827 if self._reorder is None:
819 # Since generaldelta is directly supported by cg2, reordering 828 # Since generaldelta is directly supported by cg2, reordering
820 # generally doesn't help, so we disable it by default (treating 829 # generally doesn't help, so we disable it by default (treating
821 # bundle.reorder=auto just like bundle.reorder=False). 830 # bundle.reorder=auto just like bundle.reorder=False).
822 self._reorder = False 831 self._reorder = False
925 if 'generaldelta' in repo.requirements: 934 if 'generaldelta' in repo.requirements:
926 versions.discard('01') 935 versions.discard('01')
927 assert versions 936 assert versions
928 return min(versions) 937 return min(versions)
929 938
930 def getbundler(version, repo, bundlecaps=None): 939 def getbundler(version, repo, bundlecaps=None, filematcher=None):
931 assert version in supportedoutgoingversions(repo) 940 assert version in supportedoutgoingversions(repo)
932 return _packermap[version][0](repo, bundlecaps) 941
942 if filematcher is None:
943 filematcher = matchmod.alwaysmatcher(repo.root, '')
944
945 if version == '01' and not filematcher.always():
946 raise error.ProgrammingError('version 01 changegroups do not support '
947 'sparse file matchers')
948
949 # Requested files could include files not in the local store. So
950 # filter those out.
951 filematcher = matchmod.intersectmatchers(repo.narrowmatch(),
952 filematcher)
953
954 return _packermap[version][0](repo, filematcher=filematcher,
955 bundlecaps=bundlecaps)
933 956
934 def getunbundler(version, fh, alg, extras=None): 957 def getunbundler(version, fh, alg, extras=None):
935 return _packermap[version][1](fh, alg, extras=extras) 958 return _packermap[version][1](fh, alg, extras=extras)
936 959
937 def _changegroupinfo(repo, nodes, source): 960 def _changegroupinfo(repo, nodes, source):
948 fastpath=fastpath, bundlecaps=bundlecaps) 971 fastpath=fastpath, bundlecaps=bundlecaps)
949 return getunbundler(version, util.chunkbuffer(cgstream), None, 972 return getunbundler(version, util.chunkbuffer(cgstream), None,
950 {'clcount': len(outgoing.missing) }) 973 {'clcount': len(outgoing.missing) })
951 974
952 def makestream(repo, outgoing, version, source, fastpath=False, 975 def makestream(repo, outgoing, version, source, fastpath=False,
953 bundlecaps=None): 976 bundlecaps=None, filematcher=None):
954 bundler = getbundler(version, repo, bundlecaps=bundlecaps) 977 bundler = getbundler(version, repo, bundlecaps=bundlecaps,
978 filematcher=filematcher)
955 979
956 repo = repo.unfiltered() 980 repo = repo.unfiltered()
957 commonrevs = outgoing.common 981 commonrevs = outgoing.common
958 csets = outgoing.missing 982 csets = outgoing.missing
959 heads = outgoing.missingheads 983 heads = outgoing.missingheads