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: |