Mercurial > public > mercurial-scm > hg
comparison mercurial/revlog.py @ 47012:d55b71393907
node: replace nullid and friends with nodeconstants class
The introduction of 256bit hashes require changes to nullid and other
constant magic values. Start pushing them down from repository and
revlog where sensible.
Differential Revision: https://phab.mercurial-scm.org/D9465
author | Joerg Sonnenberger <joerg@bec.de> |
---|---|
date | Mon, 29 Mar 2021 01:52:06 +0200 |
parents | 3c9208702db3 |
children | 0d8ff1f4ab0c |
comparison
equal
deleted
inserted
replaced
46992:5fa019ceb499 | 47012:d55b71393907 |
---|---|
24 | 24 |
25 # import stuff from node for others to import from revlog | 25 # import stuff from node for others to import from revlog |
26 from .node import ( | 26 from .node import ( |
27 bin, | 27 bin, |
28 hex, | 28 hex, |
29 nullhex, | |
30 nullid, | |
31 nullrev, | 29 nullrev, |
32 sha1nodeconstants, | 30 sha1nodeconstants, |
33 short, | 31 short, |
34 wdirfilenodeids, | |
35 wdirhex, | |
36 wdirid, | |
37 wdirrev, | 32 wdirrev, |
38 ) | 33 ) |
39 from .i18n import _ | 34 from .i18n import _ |
40 from .pycompat import getattr | 35 from .pycompat import getattr |
41 from .revlogutils.constants import ( | 36 from .revlogutils.constants import ( |
230 util.nouideprecwarn(msg, b'5.3', stacklevel=2) | 225 util.nouideprecwarn(msg, b'5.3', stacklevel=2) |
231 return self._nodemap | 226 return self._nodemap |
232 | 227 |
233 @util.propertycache | 228 @util.propertycache |
234 def _nodemap(self): | 229 def _nodemap(self): |
235 nodemap = nodemaputil.NodeMap({nullid: nullrev}) | 230 nodemap = nodemaputil.NodeMap({sha1nodeconstants.nullid: nullrev}) |
236 for r in range(0, len(self)): | 231 for r in range(0, len(self)): |
237 n = self[r][7] | 232 n = self[r][7] |
238 nodemap[n] = r | 233 nodemap[n] = r |
239 return nodemap | 234 return nodemap |
240 | 235 |
268 def clearcaches(self): | 263 def clearcaches(self): |
269 self.__dict__.pop('_nodemap', None) | 264 self.__dict__.pop('_nodemap', None) |
270 | 265 |
271 def __getitem__(self, i): | 266 def __getitem__(self, i): |
272 if i == -1: | 267 if i == -1: |
273 return (0, 0, 0, -1, -1, -1, -1, nullid) | 268 return (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid) |
274 return list.__getitem__(self, i) | 269 return list.__getitem__(self, i) |
275 | 270 |
276 | 271 |
277 class revlogoldio(object): | 272 class revlogoldio(object): |
278 def parseindex(self, data, inline): | 273 def parseindex(self, data, inline): |
279 s = INDEX_ENTRY_V0.size | 274 s = INDEX_ENTRY_V0.size |
280 index = [] | 275 index = [] |
281 nodemap = nodemaputil.NodeMap({nullid: nullrev}) | 276 nodemap = nodemaputil.NodeMap({sha1nodeconstants.nullid: nullrev}) |
282 n = off = 0 | 277 n = off = 0 |
283 l = len(data) | 278 l = len(data) |
284 while off + s <= l: | 279 while off + s <= l: |
285 cur = data[off : off + s] | 280 cur = data[off : off + s] |
286 off += s | 281 off += s |
816 return self.index.rev(node) | 811 return self.index.rev(node) |
817 except TypeError: | 812 except TypeError: |
818 raise | 813 raise |
819 except error.RevlogError: | 814 except error.RevlogError: |
820 # parsers.c radix tree lookup failed | 815 # parsers.c radix tree lookup failed |
821 if node == wdirid or node in wdirfilenodeids: | 816 if ( |
817 node == self.nodeconstants.wdirid | |
818 or node in self.nodeconstants.wdirfilenodeids | |
819 ): | |
822 raise error.WdirUnsupported | 820 raise error.WdirUnsupported |
823 raise error.LookupError(node, self.indexfile, _(b'no node')) | 821 raise error.LookupError(node, self.indexfile, _(b'no node')) |
824 | 822 |
825 # Accessors for index entries. | 823 # Accessors for index entries. |
826 | 824 |
907 | 905 |
908 def parents(self, node): | 906 def parents(self, node): |
909 i = self.index | 907 i = self.index |
910 d = i[self.rev(node)] | 908 d = i[self.rev(node)] |
911 # inline node() to avoid function call overhead | 909 # inline node() to avoid function call overhead |
912 if d[5] == nullid: | 910 if d[5] == self.nullid: |
913 return i[d[6]][7], i[d[5]][7] | 911 return i[d[6]][7], i[d[5]][7] |
914 else: | 912 else: |
915 return i[d[5]][7], i[d[6]][7] | 913 return i[d[5]][7], i[d[6]][7] |
916 | 914 |
917 def chainlen(self, rev): | 915 def chainlen(self, rev): |
1025 | 1023 |
1026 'heads' and 'common' are both lists of node IDs. If heads is | 1024 'heads' and 'common' are both lists of node IDs. If heads is |
1027 not supplied, uses all of the revlog's heads. If common is not | 1025 not supplied, uses all of the revlog's heads. If common is not |
1028 supplied, uses nullid.""" | 1026 supplied, uses nullid.""" |
1029 if common is None: | 1027 if common is None: |
1030 common = [nullid] | 1028 common = [self.nullid] |
1031 if heads is None: | 1029 if heads is None: |
1032 heads = self.heads() | 1030 heads = self.heads() |
1033 | 1031 |
1034 common = [self.rev(n) for n in common] | 1032 common = [self.rev(n) for n in common] |
1035 heads = [self.rev(n) for n in heads] | 1033 heads = [self.rev(n) for n in heads] |
1131 | 1129 |
1132 'heads' and 'common' are both lists of node IDs. If heads is | 1130 'heads' and 'common' are both lists of node IDs. If heads is |
1133 not supplied, uses all of the revlog's heads. If common is not | 1131 not supplied, uses all of the revlog's heads. If common is not |
1134 supplied, uses nullid.""" | 1132 supplied, uses nullid.""" |
1135 if common is None: | 1133 if common is None: |
1136 common = [nullid] | 1134 common = [self.nullid] |
1137 if heads is None: | 1135 if heads is None: |
1138 heads = self.heads() | 1136 heads = self.heads() |
1139 | 1137 |
1140 common = [self.rev(n) for n in common] | 1138 common = [self.rev(n) for n in common] |
1141 heads = [self.rev(n) for n in heads] | 1139 heads = [self.rev(n) for n in heads] |
1169 roots = list(roots) | 1167 roots = list(roots) |
1170 if not roots: | 1168 if not roots: |
1171 return nonodes | 1169 return nonodes |
1172 lowestrev = min([self.rev(n) for n in roots]) | 1170 lowestrev = min([self.rev(n) for n in roots]) |
1173 else: | 1171 else: |
1174 roots = [nullid] # Everybody's a descendant of nullid | 1172 roots = [self.nullid] # Everybody's a descendant of nullid |
1175 lowestrev = nullrev | 1173 lowestrev = nullrev |
1176 if (lowestrev == nullrev) and (heads is None): | 1174 if (lowestrev == nullrev) and (heads is None): |
1177 # We want _all_ the nodes! | 1175 # We want _all_ the nodes! |
1178 return ([self.node(r) for r in self], [nullid], list(self.heads())) | 1176 return ( |
1177 [self.node(r) for r in self], | |
1178 [self.nullid], | |
1179 list(self.heads()), | |
1180 ) | |
1179 if heads is None: | 1181 if heads is None: |
1180 # All nodes are ancestors, so the latest ancestor is the last | 1182 # All nodes are ancestors, so the latest ancestor is the last |
1181 # node. | 1183 # node. |
1182 highestrev = len(self) - 1 | 1184 highestrev = len(self) - 1 |
1183 # Set ancestors to None to signal that every node is an ancestor. | 1185 # Set ancestors to None to signal that every node is an ancestor. |
1199 highestrev = max([self.rev(n) for n in nodestotag]) | 1201 highestrev = max([self.rev(n) for n in nodestotag]) |
1200 while nodestotag: | 1202 while nodestotag: |
1201 # grab a node to tag | 1203 # grab a node to tag |
1202 n = nodestotag.pop() | 1204 n = nodestotag.pop() |
1203 # Never tag nullid | 1205 # Never tag nullid |
1204 if n == nullid: | 1206 if n == self.nullid: |
1205 continue | 1207 continue |
1206 # A node's revision number represents its place in a | 1208 # A node's revision number represents its place in a |
1207 # topologically sorted list of nodes. | 1209 # topologically sorted list of nodes. |
1208 r = self.rev(n) | 1210 r = self.rev(n) |
1209 if r >= lowestrev: | 1211 if r >= lowestrev: |
1211 # If we are possibly a descendant of one of the roots | 1213 # If we are possibly a descendant of one of the roots |
1212 # and we haven't already been marked as an ancestor | 1214 # and we haven't already been marked as an ancestor |
1213 ancestors.add(n) # Mark as ancestor | 1215 ancestors.add(n) # Mark as ancestor |
1214 # Add non-nullid parents to list of nodes to tag. | 1216 # Add non-nullid parents to list of nodes to tag. |
1215 nodestotag.update( | 1217 nodestotag.update( |
1216 [p for p in self.parents(n) if p != nullid] | 1218 [p for p in self.parents(n) if p != self.nullid] |
1217 ) | 1219 ) |
1218 elif n in heads: # We've seen it before, is it a fake head? | 1220 elif n in heads: # We've seen it before, is it a fake head? |
1219 # So it is, real heads should not be the ancestors of | 1221 # So it is, real heads should not be the ancestors of |
1220 # any other heads. | 1222 # any other heads. |
1221 heads.pop(n) | 1223 heads.pop(n) |
1239 return nonodes | 1241 return nonodes |
1240 else: | 1242 else: |
1241 # We are descending from nullid, and don't need to care about | 1243 # We are descending from nullid, and don't need to care about |
1242 # any other roots. | 1244 # any other roots. |
1243 lowestrev = nullrev | 1245 lowestrev = nullrev |
1244 roots = [nullid] | 1246 roots = [self.nullid] |
1245 # Transform our roots list into a set. | 1247 # Transform our roots list into a set. |
1246 descendants = set(roots) | 1248 descendants = set(roots) |
1247 # Also, keep the original roots so we can filter out roots that aren't | 1249 # Also, keep the original roots so we can filter out roots that aren't |
1248 # 'real' roots (i.e. are descended from other roots). | 1250 # 'real' roots (i.e. are descended from other roots). |
1249 roots = descendants.copy() | 1251 roots = descendants.copy() |
1333 if stop is specified, it will consider all the revs from stop | 1335 if stop is specified, it will consider all the revs from stop |
1334 as if they had no children | 1336 as if they had no children |
1335 """ | 1337 """ |
1336 if start is None and stop is None: | 1338 if start is None and stop is None: |
1337 if not len(self): | 1339 if not len(self): |
1338 return [nullid] | 1340 return [self.nullid] |
1339 return [self.node(r) for r in self.headrevs()] | 1341 return [self.node(r) for r in self.headrevs()] |
1340 | 1342 |
1341 if start is None: | 1343 if start is None: |
1342 start = nullrev | 1344 start = nullrev |
1343 else: | 1345 else: |
1423 except (AttributeError, OverflowError): | 1425 except (AttributeError, OverflowError): |
1424 ancs = ancestor.ancestors(self.parentrevs, a, b) | 1426 ancs = ancestor.ancestors(self.parentrevs, a, b) |
1425 if ancs: | 1427 if ancs: |
1426 # choose a consistent winner when there's a tie | 1428 # choose a consistent winner when there's a tie |
1427 return min(map(self.node, ancs)) | 1429 return min(map(self.node, ancs)) |
1428 return nullid | 1430 return self.nullid |
1429 | 1431 |
1430 def _match(self, id): | 1432 def _match(self, id): |
1431 if isinstance(id, int): | 1433 if isinstance(id, int): |
1432 # rev | 1434 # rev |
1433 return self.node(id) | 1435 return self.node(id) |
1461 except (TypeError, error.LookupError): | 1463 except (TypeError, error.LookupError): |
1462 pass | 1464 pass |
1463 | 1465 |
1464 def _partialmatch(self, id): | 1466 def _partialmatch(self, id): |
1465 # we don't care wdirfilenodeids as they should be always full hash | 1467 # we don't care wdirfilenodeids as they should be always full hash |
1466 maybewdir = wdirhex.startswith(id) | 1468 maybewdir = self.nodeconstants.wdirhex.startswith(id) |
1467 try: | 1469 try: |
1468 partial = self.index.partialmatch(id) | 1470 partial = self.index.partialmatch(id) |
1469 if partial and self.hasnode(partial): | 1471 if partial and self.hasnode(partial): |
1470 if maybewdir: | 1472 if maybewdir: |
1471 # single 'ff...' match in radix tree, ambiguous with wdir | 1473 # single 'ff...' match in radix tree, ambiguous with wdir |
1497 prefix = bin(id[: l * 2]) | 1499 prefix = bin(id[: l * 2]) |
1498 nl = [e[7] for e in self.index if e[7].startswith(prefix)] | 1500 nl = [e[7] for e in self.index if e[7].startswith(prefix)] |
1499 nl = [ | 1501 nl = [ |
1500 n for n in nl if hex(n).startswith(id) and self.hasnode(n) | 1502 n for n in nl if hex(n).startswith(id) and self.hasnode(n) |
1501 ] | 1503 ] |
1502 if nullhex.startswith(id): | 1504 if self.nodeconstants.nullhex.startswith(id): |
1503 nl.append(nullid) | 1505 nl.append(self.nullid) |
1504 if len(nl) > 0: | 1506 if len(nl) > 0: |
1505 if len(nl) == 1 and not maybewdir: | 1507 if len(nl) == 1 and not maybewdir: |
1506 self._pcache[id] = nl[0] | 1508 self._pcache[id] = nl[0] |
1507 return nl[0] | 1509 return nl[0] |
1508 raise error.AmbiguousPrefixLookupError( | 1510 raise error.AmbiguousPrefixLookupError( |
1558 if not getattr(self, 'filteredrevs', None): | 1560 if not getattr(self, 'filteredrevs', None): |
1559 try: | 1561 try: |
1560 length = max(self.index.shortest(node), minlength) | 1562 length = max(self.index.shortest(node), minlength) |
1561 return disambiguate(hexnode, length) | 1563 return disambiguate(hexnode, length) |
1562 except error.RevlogError: | 1564 except error.RevlogError: |
1563 if node != wdirid: | 1565 if node != self.nodeconstants.wdirid: |
1564 raise error.LookupError(node, self.indexfile, _(b'no node')) | 1566 raise error.LookupError(node, self.indexfile, _(b'no node')) |
1565 except AttributeError: | 1567 except AttributeError: |
1566 # Fall through to pure code | 1568 # Fall through to pure code |
1567 pass | 1569 pass |
1568 | 1570 |
1569 if node == wdirid: | 1571 if node == self.nodeconstants.wdirid: |
1570 for length in range(minlength, len(hexnode) + 1): | 1572 for length in range(minlength, len(hexnode) + 1): |
1571 prefix = hexnode[:length] | 1573 prefix = hexnode[:length] |
1572 if isvalid(prefix): | 1574 if isvalid(prefix): |
1573 return prefix | 1575 return prefix |
1574 | 1576 |
1879 else: | 1881 else: |
1880 node = nodeorrev | 1882 node = nodeorrev |
1881 rev = None | 1883 rev = None |
1882 | 1884 |
1883 # fast path the special `nullid` rev | 1885 # fast path the special `nullid` rev |
1884 if node == nullid: | 1886 if node == self.nullid: |
1885 return b"", {} | 1887 return b"", {} |
1886 | 1888 |
1887 # ``rawtext`` is the text as stored inside the revlog. Might be the | 1889 # ``rawtext`` is the text as stored inside the revlog. Might be the |
1888 # revision or might need to be processed to retrieve the revision. | 1890 # revision or might need to be processed to retrieve the revision. |
1889 rev, rawtext, validated = self._rawtext(node, rev, _df=_df) | 1891 rev, rawtext, validated = self._rawtext(node, rev, _df=_df) |
2300 | 2302 |
2301 invariants: | 2303 invariants: |
2302 - rawtext is optional (can be None); if not set, cachedelta must be set. | 2304 - rawtext is optional (can be None); if not set, cachedelta must be set. |
2303 if both are set, they must correspond to each other. | 2305 if both are set, they must correspond to each other. |
2304 """ | 2306 """ |
2305 if node == nullid: | 2307 if node == self.nullid: |
2306 raise error.RevlogError( | 2308 raise error.RevlogError( |
2307 _(b"%s: attempt to add null revision") % self.indexfile | 2309 _(b"%s: attempt to add null revision") % self.indexfile |
2308 ) | 2310 ) |
2309 if node == wdirid or node in wdirfilenodeids: | 2311 if ( |
2312 node == self.nodeconstants.wdirid | |
2313 or node in self.nodeconstants.wdirfilenodeids | |
2314 ): | |
2310 raise error.RevlogError( | 2315 raise error.RevlogError( |
2311 _(b"%s: attempt to add wdir revision") % self.indexfile | 2316 _(b"%s: attempt to add wdir revision") % self.indexfile |
2312 ) | 2317 ) |
2313 | 2318 |
2314 if self._inline: | 2319 if self._inline: |