Show More
@@ -587,6 +587,7 b' class sqlitefilestore(object):' | |||
|
587 | 587 | revisiondata=False, |
|
588 | 588 | assumehaveparentrevisions=False, |
|
589 | 589 | deltamode=repository.CG_DELTAMODE_STD, |
|
590 | sidedata_helpers=None, | |
|
590 | 591 | ): |
|
591 | 592 | if nodesorder not in (b'nodes', b'storage', b'linear', None): |
|
592 | 593 | raise error.ProgrammingError( |
@@ -625,6 +626,7 b' class sqlitefilestore(object):' | |||
|
625 | 626 | revisiondata=revisiondata, |
|
626 | 627 | assumehaveparentrevisions=assumehaveparentrevisions, |
|
627 | 628 | deltamode=deltamode, |
|
629 | sidedata_helpers=sidedata_helpers, | |
|
628 | 630 | ): |
|
629 | 631 | |
|
630 | 632 | yield delta |
@@ -272,6 +272,7 b' class cg1unpacker(object):' | |||
|
272 | 272 | url, |
|
273 | 273 | targetphase=phases.draft, |
|
274 | 274 | expectedtotal=None, |
|
275 | sidedata_categories=None, | |
|
275 | 276 | ): |
|
276 | 277 | """Add the changegroup returned by source.read() to this repo. |
|
277 | 278 | srctype is a string like 'push', 'pull', or 'unbundle'. url is |
@@ -282,9 +283,23 b' class cg1unpacker(object):' | |||
|
282 | 283 | - more heads than before: 1+added heads (2..n) |
|
283 | 284 | - fewer heads than before: -1-removed heads (-2..-n) |
|
284 | 285 | - number of heads stays the same: 1 |
|
286 | ||
|
287 | `sidedata_categories` is an optional set of the remote's sidedata wanted | |
|
288 | categories. | |
|
285 | 289 | """ |
|
286 | 290 | repo = repo.unfiltered() |
|
287 | 291 | |
|
292 | # Only useful if we're adding sidedata categories. If both peers have | |
|
293 | # the same categories, then we simply don't do anything. | |
|
294 | if self.version == b'04' and srctype == b'pull': | |
|
295 | sidedata_helpers = get_sidedata_helpers( | |
|
296 | repo, | |
|
297 | sidedata_categories or set(), | |
|
298 | pull=True, | |
|
299 | ) | |
|
300 | else: | |
|
301 | sidedata_helpers = None | |
|
302 | ||
|
288 | 303 | def csmap(x): |
|
289 | 304 | repo.ui.debug(b"add changeset %s\n" % short(x)) |
|
290 | 305 | return len(cl) |
@@ -749,6 +764,7 b' def deltagroup(' | |||
|
749 | 764 | clrevtolocalrev=None, |
|
750 | 765 | fullclnodes=None, |
|
751 | 766 | precomputedellipsis=None, |
|
767 | sidedata_helpers=None, | |
|
752 | 768 | ): |
|
753 | 769 | """Calculate deltas for a set of revisions. |
|
754 | 770 | |
@@ -756,6 +772,8 b' def deltagroup(' | |||
|
756 | 772 | |
|
757 | 773 | If topic is not None, progress detail will be generated using this |
|
758 | 774 | topic name (e.g. changesets, manifests, etc). |
|
775 | ||
|
776 | See `storageutil.emitrevisions` for the doc on `sidedata_helpers`. | |
|
759 | 777 | """ |
|
760 | 778 | if not nodes: |
|
761 | 779 | return |
@@ -854,6 +872,7 b' def deltagroup(' | |||
|
854 | 872 | revisiondata=True, |
|
855 | 873 | assumehaveparentrevisions=not ellipses, |
|
856 | 874 | deltamode=deltamode, |
|
875 | sidedata_helpers=sidedata_helpers, | |
|
857 | 876 | ) |
|
858 | 877 | |
|
859 | 878 | for i, revision in enumerate(revisions): |
@@ -974,8 +993,21 b' class cgpacker(object):' | |||
|
974 | 993 | self._verbosenote(_(b'uncompressed size of bundle content:\n')) |
|
975 | 994 | size = 0 |
|
976 | 995 | |
|
996 | sidedata_helpers = None | |
|
997 | if self.version == b'04': | |
|
998 | remote_sidedata = self._remote_sidedata | |
|
999 | if source == b'strip': | |
|
1000 | # We're our own remote when stripping, get the no-op helpers | |
|
1001 | # TODO a better approach would be for the strip bundle to | |
|
1002 | # correctly advertise its sidedata categories directly. | |
|
1003 | remote_sidedata = repo._wanted_sidedata | |
|
1004 | sidedata_helpers = get_sidedata_helpers(repo, remote_sidedata) | |
|
1005 | ||
|
977 | 1006 | clstate, deltas = self._generatechangelog( |
|
978 | cl, clnodes, generate=changelog | |
|
1007 | cl, | |
|
1008 | clnodes, | |
|
1009 | generate=changelog, | |
|
1010 | sidedata_helpers=sidedata_helpers, | |
|
979 | 1011 | ) |
|
980 | 1012 | for delta in deltas: |
|
981 | 1013 | for chunk in _revisiondeltatochunks(delta, self._builddeltaheader): |
@@ -1023,6 +1055,7 b' class cgpacker(object):' | |||
|
1023 | 1055 | fnodes, |
|
1024 | 1056 | source, |
|
1025 | 1057 | clstate[b'clrevtomanifestrev'], |
|
1058 | sidedata_helpers=sidedata_helpers, | |
|
1026 | 1059 | ) |
|
1027 | 1060 | |
|
1028 | 1061 | for tree, deltas in it: |
@@ -1063,6 +1096,7 b' class cgpacker(object):' | |||
|
1063 | 1096 | fastpathlinkrev, |
|
1064 | 1097 | fnodes, |
|
1065 | 1098 | clrevs, |
|
1099 | sidedata_helpers=sidedata_helpers, | |
|
1066 | 1100 | ) |
|
1067 | 1101 | |
|
1068 | 1102 | for path, deltas in it: |
@@ -1087,7 +1121,9 b' class cgpacker(object):' | |||
|
1087 | 1121 | if clnodes: |
|
1088 | 1122 | repo.hook(b'outgoing', node=hex(clnodes[0]), source=source) |
|
1089 | 1123 | |
|
1090 |
def _generatechangelog( |
|
|
1124 | def _generatechangelog( | |
|
1125 | self, cl, nodes, generate=True, sidedata_helpers=None | |
|
1126 | ): | |
|
1091 | 1127 | """Generate data for changelog chunks. |
|
1092 | 1128 | |
|
1093 | 1129 | Returns a 2-tuple of a dict containing state and an iterable of |
@@ -1096,6 +1132,8 b' class cgpacker(object):' | |||
|
1096 | 1132 | |
|
1097 | 1133 | if generate is False, the state will be fully populated and no chunk |
|
1098 | 1134 | stream will be yielded |
|
1135 | ||
|
1136 | See `storageutil.emitrevisions` for the doc on `sidedata_helpers`. | |
|
1099 | 1137 | """ |
|
1100 | 1138 | clrevorder = {} |
|
1101 | 1139 | manifests = {} |
@@ -1179,6 +1217,7 b' class cgpacker(object):' | |||
|
1179 | 1217 | clrevtolocalrev={}, |
|
1180 | 1218 | fullclnodes=self._fullclnodes, |
|
1181 | 1219 | precomputedellipsis=self._precomputedellipsis, |
|
1220 | sidedata_helpers=sidedata_helpers, | |
|
1182 | 1221 | ) |
|
1183 | 1222 | |
|
1184 | 1223 | return state, gen |
@@ -1192,11 +1231,14 b' class cgpacker(object):' | |||
|
1192 | 1231 | fnodes, |
|
1193 | 1232 | source, |
|
1194 | 1233 | clrevtolocalrev, |
|
1234 | sidedata_helpers=None, | |
|
1195 | 1235 | ): |
|
1196 | 1236 | """Returns an iterator of changegroup chunks containing manifests. |
|
1197 | 1237 | |
|
1198 | 1238 | `source` is unused here, but is used by extensions like remotefilelog to |
|
1199 | 1239 | change what is sent based in pulls vs pushes, etc. |
|
1240 | ||
|
1241 | See `storageutil.emitrevisions` for the doc on `sidedata_helpers`. | |
|
1200 | 1242 | """ |
|
1201 | 1243 | repo = self._repo |
|
1202 | 1244 | mfl = repo.manifestlog |
@@ -1285,6 +1327,7 b' class cgpacker(object):' | |||
|
1285 | 1327 | clrevtolocalrev=clrevtolocalrev, |
|
1286 | 1328 | fullclnodes=self._fullclnodes, |
|
1287 | 1329 | precomputedellipsis=self._precomputedellipsis, |
|
1330 | sidedata_helpers=sidedata_helpers, | |
|
1288 | 1331 | ) |
|
1289 | 1332 | |
|
1290 | 1333 | if not self._oldmatcher.visitdir(store.tree[:-1]): |
@@ -1323,6 +1366,7 b' class cgpacker(object):' | |||
|
1323 | 1366 | fastpathlinkrev, |
|
1324 | 1367 | fnodes, |
|
1325 | 1368 | clrevs, |
|
1369 | sidedata_helpers=None, | |
|
1326 | 1370 | ): |
|
1327 | 1371 | changedfiles = [ |
|
1328 | 1372 | f |
@@ -1417,6 +1461,7 b' class cgpacker(object):' | |||
|
1417 | 1461 | clrevtolocalrev=clrevtolocalrev, |
|
1418 | 1462 | fullclnodes=self._fullclnodes, |
|
1419 | 1463 | precomputedellipsis=self._precomputedellipsis, |
|
1464 | sidedata_helpers=sidedata_helpers, | |
|
1420 | 1465 | ) |
|
1421 | 1466 | |
|
1422 | 1467 | yield fname, deltas |
@@ -1792,3 +1837,25 b' def _addchangegroupfiles(repo, source, r' | |||
|
1792 | 1837 | ) |
|
1793 | 1838 | |
|
1794 | 1839 | return revisions, files |
|
1840 | ||
|
1841 | ||
|
1842 | def get_sidedata_helpers(repo, remote_sd_categories, pull=False): | |
|
1843 | # Computers for computing sidedata on-the-fly | |
|
1844 | sd_computers = collections.defaultdict(list) | |
|
1845 | # Computers for categories to remove from sidedata | |
|
1846 | sd_removers = collections.defaultdict(list) | |
|
1847 | ||
|
1848 | to_generate = remote_sd_categories - repo._wanted_sidedata | |
|
1849 | to_remove = repo._wanted_sidedata - remote_sd_categories | |
|
1850 | if pull: | |
|
1851 | to_generate, to_remove = to_remove, to_generate | |
|
1852 | ||
|
1853 | for revlog_kind, computers in repo._sidedata_computers.items(): | |
|
1854 | for category, computer in computers.items(): | |
|
1855 | if category in to_generate: | |
|
1856 | sd_computers[revlog_kind].append(computer) | |
|
1857 | if category in to_remove: | |
|
1858 | sd_removers[revlog_kind].append(computer) | |
|
1859 | ||
|
1860 | sidedata_helpers = (repo, sd_computers, sd_removers) | |
|
1861 | return sidedata_helpers |
@@ -103,6 +103,7 b' class filelog(object):' | |||
|
103 | 103 | revisiondata=False, |
|
104 | 104 | assumehaveparentrevisions=False, |
|
105 | 105 | deltamode=repository.CG_DELTAMODE_STD, |
|
106 | sidedata_helpers=None, | |
|
106 | 107 | ): |
|
107 | 108 | return self._revlog.emitrevisions( |
|
108 | 109 | nodes, |
@@ -110,6 +111,7 b' class filelog(object):' | |||
|
110 | 111 | revisiondata=revisiondata, |
|
111 | 112 | assumehaveparentrevisions=assumehaveparentrevisions, |
|
112 | 113 | deltamode=deltamode, |
|
114 | sidedata_helpers=sidedata_helpers, | |
|
113 | 115 | ) |
|
114 | 116 | |
|
115 | 117 | def addrevision( |
@@ -1826,6 +1826,7 b' class manifestrevlog(object):' | |||
|
1826 | 1826 | revisiondata=False, |
|
1827 | 1827 | assumehaveparentrevisions=False, |
|
1828 | 1828 | deltamode=repository.CG_DELTAMODE_STD, |
|
1829 | sidedata_helpers=None, | |
|
1829 | 1830 | ): |
|
1830 | 1831 | return self._revlog.emitrevisions( |
|
1831 | 1832 | nodes, |
@@ -1833,6 +1834,7 b' class manifestrevlog(object):' | |||
|
1833 | 1834 | revisiondata=revisiondata, |
|
1834 | 1835 | assumehaveparentrevisions=assumehaveparentrevisions, |
|
1835 | 1836 | deltamode=deltamode, |
|
1837 | sidedata_helpers=sidedata_helpers, | |
|
1836 | 1838 | ) |
|
1837 | 1839 | |
|
1838 | 1840 | def addgroup( |
@@ -2733,6 +2733,7 b' class revlog(object):' | |||
|
2733 | 2733 | revisiondata=False, |
|
2734 | 2734 | assumehaveparentrevisions=False, |
|
2735 | 2735 | deltamode=repository.CG_DELTAMODE_STD, |
|
2736 | sidedata_helpers=None, | |
|
2736 | 2737 | ): |
|
2737 | 2738 | if nodesorder not in (b'nodes', b'storage', b'linear', None): |
|
2738 | 2739 | raise error.ProgrammingError( |
@@ -2761,6 +2762,7 b' class revlog(object):' | |||
|
2761 | 2762 | deltamode=deltamode, |
|
2762 | 2763 | revisiondata=revisiondata, |
|
2763 | 2764 | assumehaveparentrevisions=assumehaveparentrevisions, |
|
2765 | sidedata_helpers=sidedata_helpers, | |
|
2764 | 2766 | ) |
|
2765 | 2767 | |
|
2766 | 2768 | DELTAREUSEALWAYS = b'always' |
@@ -23,6 +23,7 b' from .. import (' | |||
|
23 | 23 | pycompat, |
|
24 | 24 | ) |
|
25 | 25 | from ..interfaces import repository |
|
26 | from ..revlogutils import sidedata as sidedatamod | |
|
26 | 27 | from ..utils import hashutil |
|
27 | 28 | |
|
28 | 29 | _nullhash = hashutil.sha1(nullid) |
@@ -294,6 +295,7 b' def emitrevisions(' | |||
|
294 | 295 | deltamode=repository.CG_DELTAMODE_STD, |
|
295 | 296 | revisiondata=False, |
|
296 | 297 | assumehaveparentrevisions=False, |
|
298 | sidedata_helpers=None, | |
|
297 | 299 | ): |
|
298 | 300 | """Generic implementation of ifiledata.emitrevisions(). |
|
299 | 301 | |
@@ -356,6 +358,21 b' def emitrevisions(' | |||
|
356 | 358 | ``nodesorder`` |
|
357 | 359 | ``revisiondata`` |
|
358 | 360 | ``assumehaveparentrevisions`` |
|
361 | ``sidedata_helpers`` (optional) | |
|
362 | If not None, means that sidedata should be included. | |
|
363 | A dictionary of revlog type to tuples of `(repo, computers, removers)`: | |
|
364 | * `repo` is used as an argument for computers | |
|
365 | * `computers` is a list of `(category, (keys, computer)` that | |
|
366 | compute the missing sidedata categories that were asked: | |
|
367 | * `category` is the sidedata category | |
|
368 | * `keys` are the sidedata keys to be affected | |
|
369 | * `computer` is the function `(repo, store, rev, sidedata)` that | |
|
370 | returns a new sidedata dict. | |
|
371 | * `removers` will remove the keys corresponding to the categories | |
|
372 | that are present, but not needed. | |
|
373 | If both `computers` and `removers` are empty, sidedata are simply not | |
|
374 | transformed. | |
|
375 | Revlog types are `changelog`, `manifest` or `filelog`. | |
|
359 | 376 | """ |
|
360 | 377 | |
|
361 | 378 | fnode = store.node |
@@ -469,6 +486,17 b' def emitrevisions(' | |||
|
469 | 486 | |
|
470 | 487 | available.add(rev) |
|
471 | 488 | |
|
489 | sidedata = None | |
|
490 | if sidedata_helpers: | |
|
491 | sidedata = store.sidedata(rev) | |
|
492 | sidedata = run_sidedata_helpers( | |
|
493 | store=store, | |
|
494 | sidedata_helpers=sidedata_helpers, | |
|
495 | sidedata=sidedata, | |
|
496 | rev=rev, | |
|
497 | ) | |
|
498 | sidedata = sidedatamod.serialize_sidedata(sidedata) | |
|
499 | ||
|
472 | 500 | yield resultcls( |
|
473 | 501 | node=node, |
|
474 | 502 | p1node=fnode(p1rev), |
@@ -484,6 +512,25 b' def emitrevisions(' | |||
|
484 | 512 | prevrev = rev |
|
485 | 513 | |
|
486 | 514 | |
|
515 | def run_sidedata_helpers(store, sidedata_helpers, sidedata, rev): | |
|
516 | """Returns the sidedata for the given revision after running through | |
|
517 | the given helpers. | |
|
518 | - `store`: the revlog this applies to (changelog, manifest, or filelog | |
|
519 | instance) | |
|
520 | - `sidedata_helpers`: see `storageutil.emitrevisions` | |
|
521 | - `sidedata`: previous sidedata at the given rev, if any | |
|
522 | - `rev`: affected rev of `store` | |
|
523 | """ | |
|
524 | repo, sd_computers, sd_removers = sidedata_helpers | |
|
525 | kind = store.revlog_kind | |
|
526 | for _keys, sd_computer in sd_computers.get(kind, []): | |
|
527 | sidedata = sd_computer(repo, store, rev, sidedata) | |
|
528 | for keys, _computer in sd_removers.get(kind, []): | |
|
529 | for key in keys: | |
|
530 | sidedata.pop(key, None) | |
|
531 | return sidedata | |
|
532 | ||
|
533 | ||
|
487 | 534 | def deltaiscensored(delta, baserev, baselenfn): |
|
488 | 535 | """Determine if a delta represents censored revision data. |
|
489 | 536 |
@@ -446,6 +446,7 b' class filestorage(object):' | |||
|
446 | 446 | revisiondata=False, |
|
447 | 447 | assumehaveparentrevisions=False, |
|
448 | 448 | deltamode=repository.CG_DELTAMODE_STD, |
|
449 | sidedata_helpers=None, | |
|
449 | 450 | ): |
|
450 | 451 | # TODO this will probably break on some ordering options. |
|
451 | 452 | nodes = [n for n in nodes if n != nullid] |
@@ -459,6 +460,7 b' class filestorage(object):' | |||
|
459 | 460 | revisiondata=revisiondata, |
|
460 | 461 | assumehaveparentrevisions=assumehaveparentrevisions, |
|
461 | 462 | deltamode=deltamode, |
|
463 | sidedata_helpers=sidedata_helpers, | |
|
462 | 464 | ): |
|
463 | 465 | yield delta |
|
464 | 466 |
General Comments 0
You need to be logged in to leave comments.
Login now