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