##// END OF EJS Templates
sidedata-exchange: add `wanted_sidedata` and `sidedata_computers` to repos...
Raphaël Gomès -
r47447:bc251951 default
parent child Browse files
Show More
@@ -1812,6 +1812,28 b' def _formatrequirementsparams(requiremen'
1812 return params
1812 return params
1813
1813
1814
1814
1815 def format_remote_wanted_sidedata(repo):
1816 """Formats a repo's wanted sidedata categories into a bytestring for
1817 capabilities exchange."""
1818 wanted = b""
1819 if repo._wanted_sidedata:
1820 wanted = b','.join(
1821 pycompat.bytestr(c) for c in sorted(repo._wanted_sidedata)
1822 )
1823 return wanted
1824
1825
1826 def read_remote_wanted_sidedata(remote):
1827 sidedata_categories = remote.capable(b'exp-wanted-sidedata')
1828 return read_wanted_sidedata(sidedata_categories)
1829
1830
1831 def read_wanted_sidedata(formatted):
1832 if formatted:
1833 return set(formatted.split(b','))
1834 return set()
1835
1836
1815 def addpartbundlestream2(bundler, repo, **kwargs):
1837 def addpartbundlestream2(bundler, repo, **kwargs):
1816 if not kwargs.get('stream', False):
1838 if not kwargs.get('stream', False):
1817 return
1839 return
@@ -1957,6 +1979,7 b' def combinechangegroupresults(op):'
1957 b'version',
1979 b'version',
1958 b'nbchanges',
1980 b'nbchanges',
1959 b'exp-sidedata',
1981 b'exp-sidedata',
1982 b'exp-wanted-sidedata',
1960 b'treemanifest',
1983 b'treemanifest',
1961 b'targetphase',
1984 b'targetphase',
1962 ),
1985 ),
@@ -1999,6 +2022,10 b' def handlechangegroup(op, inpart):'
1999 targetphase = inpart.params.get(b'targetphase')
2022 targetphase = inpart.params.get(b'targetphase')
2000 if targetphase is not None:
2023 if targetphase is not None:
2001 extrakwargs['targetphase'] = int(targetphase)
2024 extrakwargs['targetphase'] = int(targetphase)
2025
2026 remote_sidedata = inpart.params.get(b'exp-wanted-sidedata')
2027 extrakwargs['sidedata_categories'] = read_wanted_sidedata(remote_sidedata)
2028
2002 ret = _processchangegroup(
2029 ret = _processchangegroup(
2003 op,
2030 op,
2004 cg,
2031 cg,
@@ -2559,5 +2586,7 b' def widen_bundle('
2559 part.addparam(b'treemanifest', b'1')
2586 part.addparam(b'treemanifest', b'1')
2560 if b'exp-sidedata-flag' in repo.requirements:
2587 if b'exp-sidedata-flag' in repo.requirements:
2561 part.addparam(b'exp-sidedata', b'1')
2588 part.addparam(b'exp-sidedata', b'1')
2589 wanted = format_remote_wanted_sidedata(repo)
2590 part.addparam(b'exp-wanted-sidedata', wanted)
2562
2591
2563 return bundler
2592 return bundler
@@ -945,6 +945,9 b' class cgpacker(object):'
945 if bundlecaps is None:
945 if bundlecaps is None:
946 bundlecaps = set()
946 bundlecaps = set()
947 self._bundlecaps = bundlecaps
947 self._bundlecaps = bundlecaps
948 if remote_sidedata is None:
949 remote_sidedata = set()
950 self._remote_sidedata = remote_sidedata
948 self._isshallow = shallow
951 self._isshallow = shallow
949 self._fullclnodes = fullnodes
952 self._fullclnodes = fullnodes
950
953
@@ -420,7 +420,20 b' def push('
420 b'unbundle wire protocol command'
420 b'unbundle wire protocol command'
421 )
421 )
422 )
422 )
423
423 for category in sorted(bundle2.read_remote_wanted_sidedata(pushop.remote)):
424 # Check that a computer is registered for that category for at least
425 # one revlog kind.
426 for kind, computers in repo._sidedata_computers.items():
427 if computers.get(category):
428 break
429 else:
430 raise error.Abort(
431 _(
432 b'cannot push: required sidedata category not supported'
433 b" by this client: '%s'"
434 )
435 % pycompat.bytestr(category)
436 )
424 # get lock as we might write phase data
437 # get lock as we might write phase data
425 wlock = lock = None
438 wlock = lock = None
426 try:
439 try:
@@ -865,8 +878,15 b' def _pushb2ctx(pushop, bundler):'
865 if not cgversions:
878 if not cgversions:
866 raise error.Abort(_(b'no common changegroup version'))
879 raise error.Abort(_(b'no common changegroup version'))
867 version = max(cgversions)
880 version = max(cgversions)
881
882 remote_sidedata = bundle2.read_remote_wanted_sidedata(pushop.remote)
868 cgstream = changegroup.makestream(
883 cgstream = changegroup.makestream(
869 pushop.repo, pushop.outgoing, version, b'push'
884 pushop.repo,
885 pushop.outgoing,
886 version,
887 b'push',
888 bundlecaps=b2caps,
889 remote_sidedata=remote_sidedata,
870 )
890 )
871 cgpart = bundler.newpart(b'changegroup', data=cgstream)
891 cgpart = bundler.newpart(b'changegroup', data=cgstream)
872 if cgversions:
892 if cgversions:
@@ -1607,6 +1627,23 b' def pull('
1607 ) % (b', '.join(sorted(missing)))
1627 ) % (b', '.join(sorted(missing)))
1608 raise error.Abort(msg)
1628 raise error.Abort(msg)
1609
1629
1630 for category in repo._wanted_sidedata:
1631 # Check that a computer is registered for that category for at least
1632 # one revlog kind.
1633 for kind, computers in repo._sidedata_computers.items():
1634 if computers.get(category):
1635 break
1636 else:
1637 # This should never happen since repos are supposed to be able to
1638 # generate the sidedata they require.
1639 raise error.ProgrammingError(
1640 _(
1641 b'sidedata category requested by local side without local'
1642 b"support: '%s'"
1643 )
1644 % pycompat.bytestr(category)
1645 )
1646
1610 pullop.trmanager = transactionmanager(repo, b'pull', remote.url())
1647 pullop.trmanager = transactionmanager(repo, b'pull', remote.url())
1611 wlock = util.nullcontextmanager()
1648 wlock = util.nullcontextmanager()
1612 if not bookmod.bookmarksinstore(repo):
1649 if not bookmod.bookmarksinstore(repo):
@@ -1820,6 +1857,10 b' def _pullbundle2(pullop):'
1820 pullop.stepsdone.add(b'obsmarkers')
1857 pullop.stepsdone.add(b'obsmarkers')
1821 _pullbundle2extraprepare(pullop, kwargs)
1858 _pullbundle2extraprepare(pullop, kwargs)
1822
1859
1860 remote_sidedata = bundle2.read_remote_wanted_sidedata(pullop.remote)
1861 if remote_sidedata:
1862 kwargs[b'remote_sidedata'] = remote_sidedata
1863
1823 with pullop.remote.commandexecutor() as e:
1864 with pullop.remote.commandexecutor() as e:
1824 args = dict(kwargs)
1865 args = dict(kwargs)
1825 args[b'source'] = b'pull'
1866 args[b'source'] = b'pull'
@@ -2388,6 +2429,8 b' def _getbundlechangegrouppart('
2388
2429
2389 if b'exp-sidedata-flag' in repo.requirements:
2430 if b'exp-sidedata-flag' in repo.requirements:
2390 part.addparam(b'exp-sidedata', b'1')
2431 part.addparam(b'exp-sidedata', b'1')
2432 sidedata = bundle2.format_remote_wanted_sidedata(repo)
2433 part.addparam(b'exp-wanted-sidedata', sidedata)
2391
2434
2392 if (
2435 if (
2393 kwargs.get('narrow', False)
2436 kwargs.get('narrow', False)
@@ -1832,6 +1832,12 b' class ilocalrepositorymain(interfaceutil'
1832 def savecommitmessage(text):
1832 def savecommitmessage(text):
1833 pass
1833 pass
1834
1834
1835 def register_sidedata_computer(kind, category, keys, computer):
1836 pass
1837
1838 def register_wanted_sidedata(category):
1839 pass
1840
1835
1841
1836 class completelocalrepository(
1842 class completelocalrepository(
1837 ilocalrepositorymain, ilocalrepositoryfilestorage
1843 ilocalrepositorymain, ilocalrepositoryfilestorage
@@ -49,6 +49,7 b' from . import ('
49 match as matchmod,
49 match as matchmod,
50 mergestate as mergestatemod,
50 mergestate as mergestatemod,
51 mergeutil,
51 mergeutil,
52 metadata as metadatamod,
52 namespaces,
53 namespaces,
53 narrowspec,
54 narrowspec,
54 obsolete,
55 obsolete,
@@ -273,6 +274,11 b' class localpeer(repository.peer):'
273 caps = moderncaps.copy()
274 caps = moderncaps.copy()
274 self._repo = repo.filtered(b'served')
275 self._repo = repo.filtered(b'served')
275 self.ui = repo.ui
276 self.ui = repo.ui
277
278 if repo._wanted_sidedata:
279 formatted = bundle2.format_remote_wanted_sidedata(repo)
280 caps.add(b'exp-wanted-sidedata=' + formatted)
281
276 self._caps = repo._restrictcapabilities(caps)
282 self._caps = repo._restrictcapabilities(caps)
277
283
278 # Begin of _basepeer interface.
284 # Begin of _basepeer interface.
@@ -1395,6 +1401,10 b' class localrepository(object):'
1395 if requirementsmod.COPIESSDC_REQUIREMENT in self.requirements:
1401 if requirementsmod.COPIESSDC_REQUIREMENT in self.requirements:
1396 self.filecopiesmode = b'changeset-sidedata'
1402 self.filecopiesmode = b'changeset-sidedata'
1397
1403
1404 self._wanted_sidedata = set()
1405 self._sidedata_computers = {}
1406 metadatamod.set_sidedata_spec_for_repo(self)
1407
1398 def _getvfsward(self, origfunc):
1408 def _getvfsward(self, origfunc):
1399 """build a ward for self.vfs"""
1409 """build a ward for self.vfs"""
1400 rref = weakref.ref(self)
1410 rref = weakref.ref(self)
@@ -3332,6 +3342,22 b' class localrepository(object):'
3332 fp.close()
3342 fp.close()
3333 return self.pathto(fp.name[len(self.root) + 1 :])
3343 return self.pathto(fp.name[len(self.root) + 1 :])
3334
3344
3345 def register_wanted_sidedata(self, category):
3346 self._wanted_sidedata.add(pycompat.bytestr(category))
3347
3348 def register_sidedata_computer(self, kind, category, keys, computer):
3349 if kind not in (b"changelog", b"manifest", b"filelog"):
3350 msg = _(b"unexpected revlog kind '%s'.")
3351 raise error.ProgrammingError(msg % kind)
3352 category = pycompat.bytestr(category)
3353 if category in self._sidedata_computers.get(kind, []):
3354 msg = _(
3355 b"cannot register a sidedata computer twice for category '%s'."
3356 )
3357 raise error.ProgrammingError(msg % category)
3358 self._sidedata_computers.setdefault(kind, {})
3359 self._sidedata_computers[kind][category] = (keys, computer)
3360
3335
3361
3336 # used to avoid circular references so destructors work
3362 # used to avoid circular references so destructors work
3337 def aftertrans(files):
3363 def aftertrans(files):
@@ -18,6 +18,7 b' from .node import ('
18 from . import (
18 from . import (
19 error,
19 error,
20 pycompat,
20 pycompat,
21 requirements as requirementsmod,
21 util,
22 util,
22 )
23 )
23
24
@@ -804,6 +805,21 b' def _getsidedata(srcrepo, rev):'
804 return encode_files_sidedata(files), files.has_copies_info
805 return encode_files_sidedata(files), files.has_copies_info
805
806
806
807
808 def copies_sidedata_computer(repo, revlog, rev, existing_sidedata):
809 return _getsidedata(repo, rev)[0]
810
811
812 def set_sidedata_spec_for_repo(repo):
813 if requirementsmod.COPIESSDC_REQUIREMENT in repo.requirements:
814 repo.register_wanted_sidedata(sidedatamod.SD_FILES)
815 repo.register_sidedata_computer(
816 b"changelog",
817 sidedatamod.SD_FILES,
818 (sidedatamod.SD_FILES,),
819 copies_sidedata_computer,
820 )
821
822
807 def getsidedataadder(srcrepo, destrepo):
823 def getsidedataadder(srcrepo, destrepo):
808 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade')
824 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade')
809 if pycompat.iswindows or not use_w:
825 if pycompat.iswindows or not use_w:
@@ -172,6 +172,7 b' class statichttprepository('
172 self.names = namespaces.namespaces()
172 self.names = namespaces.namespaces()
173 self.filtername = None
173 self.filtername = None
174 self._extrafilterid = None
174 self._extrafilterid = None
175 self._wanted_sidedata = set()
175
176
176 try:
177 try:
177 requirements = set(self.vfs.read(b'requires').splitlines())
178 requirements = set(self.vfs.read(b'requires').splitlines())
@@ -85,6 +85,7 b' def checkzobject(o, allowextra=False):'
85 class dummyrepo(object):
85 class dummyrepo(object):
86 def __init__(self):
86 def __init__(self):
87 self.ui = uimod.ui()
87 self.ui = uimod.ui()
88 self._wanted_sidedata = set()
88
89
89 def filtered(self, name):
90 def filtered(self, name):
90 pass
91 pass
General Comments 0
You need to be logged in to leave comments. Login now