364 raise SQLiteStoreError( |
363 raise SQLiteStoreError( |
365 _(b'sqlite database has inconsistent revision numbers') |
364 _(b'sqlite database has inconsistent revision numbers') |
366 ) |
365 ) |
367 |
366 |
368 if p1rev == nullrev: |
367 if p1rev == nullrev: |
369 p1node = nullid |
368 p1node = sha1nodeconstants.nullid |
370 else: |
369 else: |
371 p1node = self._revtonode[p1rev] |
370 p1node = self._revtonode[p1rev] |
372 |
371 |
373 if p2rev == nullrev: |
372 if p2rev == nullrev: |
374 p2node = nullid |
373 p2node = sha1nodeconstants.nullid |
375 else: |
374 else: |
376 p2node = self._revtonode[p2rev] |
375 p2node = self._revtonode[p2rev] |
377 |
376 |
378 entry = revisionentry( |
377 entry = revisionentry( |
379 rid=rid, |
378 rid=rid, |
398 |
397 |
399 def __iter__(self): |
398 def __iter__(self): |
400 return iter(pycompat.xrange(len(self._revisions))) |
399 return iter(pycompat.xrange(len(self._revisions))) |
401 |
400 |
402 def hasnode(self, node): |
401 def hasnode(self, node): |
403 if node == nullid: |
402 if node == sha1nodeconstants.nullid: |
404 return False |
403 return False |
405 |
404 |
406 return node in self._nodetorev |
405 return node in self._nodetorev |
407 |
406 |
408 def revs(self, start=0, stop=None): |
407 def revs(self, start=0, stop=None): |
409 return storageutil.iterrevs( |
408 return storageutil.iterrevs( |
410 len(self._revisions), start=start, stop=stop |
409 len(self._revisions), start=start, stop=stop |
411 ) |
410 ) |
412 |
411 |
413 def parents(self, node): |
412 def parents(self, node): |
414 if node == nullid: |
413 if node == sha1nodeconstants.nullid: |
415 return nullid, nullid |
414 return sha1nodeconstants.nullid, sha1nodeconstants.nullid |
416 |
415 |
417 if node not in self._revisions: |
416 if node not in self._revisions: |
418 raise error.LookupError(node, self._path, _(b'no node')) |
417 raise error.LookupError(node, self._path, _(b'no node')) |
419 |
418 |
420 entry = self._revisions[node] |
419 entry = self._revisions[node] |
429 |
428 |
430 entry = self._revisions[self._revtonode[rev]] |
429 entry = self._revisions[self._revtonode[rev]] |
431 return entry.p1rev, entry.p2rev |
430 return entry.p1rev, entry.p2rev |
432 |
431 |
433 def rev(self, node): |
432 def rev(self, node): |
434 if node == nullid: |
433 if node == sha1nodeconstants.nullid: |
435 return nullrev |
434 return nullrev |
436 |
435 |
437 if node not in self._nodetorev: |
436 if node not in self._nodetorev: |
438 raise error.LookupError(node, self._path, _(b'no node')) |
437 raise error.LookupError(node, self._path, _(b'no node')) |
439 |
438 |
440 return self._nodetorev[node] |
439 return self._nodetorev[node] |
441 |
440 |
442 def node(self, rev): |
441 def node(self, rev): |
443 if rev == nullrev: |
442 if rev == nullrev: |
444 return nullid |
443 return sha1nodeconstants.nullid |
445 |
444 |
446 if rev not in self._revtonode: |
445 if rev not in self._revtonode: |
447 raise IndexError(rev) |
446 raise IndexError(rev) |
448 |
447 |
449 return self._revtonode[rev] |
448 return self._revtonode[rev] |
483 return dagop.descendantrevs(revs, self.revs, self.parentrevs) |
482 return dagop.descendantrevs(revs, self.revs, self.parentrevs) |
484 |
483 |
485 def heads(self, start=None, stop=None): |
484 def heads(self, start=None, stop=None): |
486 if start is None and stop is None: |
485 if start is None and stop is None: |
487 if not len(self): |
486 if not len(self): |
488 return [nullid] |
487 return [sha1nodeconstants.nullid] |
489 |
488 |
490 startrev = self.rev(start) if start is not None else nullrev |
489 startrev = self.rev(start) if start is not None else nullrev |
491 stoprevs = {self.rev(n) for n in stop or []} |
490 stoprevs = {self.rev(n) for n in stop or []} |
492 |
491 |
493 revs = dagop.headrevssubset( |
492 revs = dagop.headrevssubset( |
527 return len(self.read(node)) |
526 return len(self.read(node)) |
528 |
527 |
529 return len(self.revision(node)) |
528 return len(self.revision(node)) |
530 |
529 |
531 def revision(self, node, raw=False, _verifyhash=True): |
530 def revision(self, node, raw=False, _verifyhash=True): |
532 if node in (nullid, nullrev): |
531 if node in (sha1nodeconstants.nullid, nullrev): |
533 return b'' |
532 return b'' |
534 |
533 |
535 if isinstance(node, int): |
534 if isinstance(node, int): |
536 node = self.node(node) |
535 node = self.node(node) |
537 |
536 |
594 if nodesorder not in (b'nodes', b'storage', b'linear', None): |
593 if nodesorder not in (b'nodes', b'storage', b'linear', None): |
595 raise error.ProgrammingError( |
594 raise error.ProgrammingError( |
596 b'unhandled value for nodesorder: %s' % nodesorder |
595 b'unhandled value for nodesorder: %s' % nodesorder |
597 ) |
596 ) |
598 |
597 |
599 nodes = [n for n in nodes if n != nullid] |
598 nodes = [n for n in nodes if n != sha1nodeconstants.nullid] |
600 |
599 |
601 if not nodes: |
600 if not nodes: |
602 return |
601 return |
603 |
602 |
604 # TODO perform in a single query. |
603 # TODO perform in a single query. |
703 |
702 |
704 if wireflags & ~repository.REVISION_FLAG_CENSORED: |
703 if wireflags & ~repository.REVISION_FLAG_CENSORED: |
705 raise SQLiteStoreError(b'unhandled revision flag') |
704 raise SQLiteStoreError(b'unhandled revision flag') |
706 |
705 |
707 if maybemissingparents: |
706 if maybemissingparents: |
708 if p1 != nullid and not self.hasnode(p1): |
707 if p1 != sha1nodeconstants.nullid and not self.hasnode(p1): |
709 p1 = nullid |
708 p1 = sha1nodeconstants.nullid |
710 storeflags |= FLAG_MISSING_P1 |
709 storeflags |= FLAG_MISSING_P1 |
711 |
710 |
712 if p2 != nullid and not self.hasnode(p2): |
711 if p2 != sha1nodeconstants.nullid and not self.hasnode(p2): |
713 p2 = nullid |
712 p2 = sha1nodeconstants.nullid |
714 storeflags |= FLAG_MISSING_P2 |
713 storeflags |= FLAG_MISSING_P2 |
715 |
714 |
716 baserev = self.rev(deltabase) |
715 baserev = self.rev(deltabase) |
717 |
716 |
718 # If base is censored, delta must be full replacement in a single |
717 # If base is censored, delta must be full replacement in a single |
734 |
733 |
735 if node in self._revisions: |
734 if node in self._revisions: |
736 # Possibly reset parents to make them proper. |
735 # Possibly reset parents to make them proper. |
737 entry = self._revisions[node] |
736 entry = self._revisions[node] |
738 |
737 |
739 if entry.flags & FLAG_MISSING_P1 and p1 != nullid: |
738 if ( |
|
739 entry.flags & FLAG_MISSING_P1 |
|
740 and p1 != sha1nodeconstants.nullid |
|
741 ): |
740 entry.p1node = p1 |
742 entry.p1node = p1 |
741 entry.p1rev = self._nodetorev[p1] |
743 entry.p1rev = self._nodetorev[p1] |
742 entry.flags &= ~FLAG_MISSING_P1 |
744 entry.flags &= ~FLAG_MISSING_P1 |
743 |
745 |
744 self._db.execute( |
746 self._db.execute( |
745 'UPDATE fileindex SET p1rev=?, flags=? WHERE id=?', |
747 'UPDATE fileindex SET p1rev=?, flags=? WHERE id=?', |
746 (self._nodetorev[p1], entry.flags, entry.rid), |
748 (self._nodetorev[p1], entry.flags, entry.rid), |
747 ) |
749 ) |
748 |
750 |
749 if entry.flags & FLAG_MISSING_P2 and p2 != nullid: |
751 if ( |
|
752 entry.flags & FLAG_MISSING_P2 |
|
753 and p2 != sha1nodeconstants.nullid |
|
754 ): |
750 entry.p2node = p2 |
755 entry.p2node = p2 |
751 entry.p2rev = self._nodetorev[p2] |
756 entry.p2rev = self._nodetorev[p2] |
752 entry.flags &= ~FLAG_MISSING_P2 |
757 entry.flags &= ~FLAG_MISSING_P2 |
753 |
758 |
754 self._db.execute( |
759 self._db.execute( |
759 if duplicaterevisioncb: |
764 if duplicaterevisioncb: |
760 duplicaterevisioncb(self, self.rev(node)) |
765 duplicaterevisioncb(self, self.rev(node)) |
761 empty = False |
766 empty = False |
762 continue |
767 continue |
763 |
768 |
764 if deltabase == nullid: |
769 if deltabase == sha1nodeconstants.nullid: |
765 text = mdiff.patch(b'', delta) |
770 text = mdiff.patch(b'', delta) |
766 storedelta = None |
771 storedelta = None |
767 else: |
772 else: |
768 text = None |
773 text = None |
769 storedelta = (deltabase, delta) |
774 storedelta = (deltabase, delta) |
1010 |
1015 |
1011 else: |
1016 else: |
1012 assert revisiondata is not None |
1017 assert revisiondata is not None |
1013 deltabase = p1 |
1018 deltabase = p1 |
1014 |
1019 |
1015 if deltabase == nullid: |
1020 if deltabase == sha1nodeconstants.nullid: |
1016 delta = revisiondata |
1021 delta = revisiondata |
1017 else: |
1022 else: |
1018 delta = mdiff.textdiff( |
1023 delta = mdiff.textdiff( |
1019 self.revision(self.rev(deltabase)), revisiondata |
1024 self.revision(self.rev(deltabase)), revisiondata |
1020 ) |
1025 ) |
1021 |
1026 |
1022 # File index stores a pointer to its delta and the parent delta. |
1027 # File index stores a pointer to its delta and the parent delta. |
1023 # The parent delta is stored via a pointer to the fileindex PK. |
1028 # The parent delta is stored via a pointer to the fileindex PK. |
1024 if deltabase == nullid: |
1029 if deltabase == sha1nodeconstants.nullid: |
1025 baseid = None |
1030 baseid = None |
1026 else: |
1031 else: |
1027 baseid = self._revisions[deltabase].rid |
1032 baseid = self._revisions[deltabase].rid |
1028 |
1033 |
1029 # Deltas are stored with a hash of their content. This allows |
1034 # Deltas are stored with a hash of their content. This allows |
1053 |
1058 |
1054 deltaid = insertdelta(self._db, compression, deltahash, deltablob) |
1059 deltaid = insertdelta(self._db, compression, deltahash, deltablob) |
1055 |
1060 |
1056 rev = len(self) |
1061 rev = len(self) |
1057 |
1062 |
1058 if p1 == nullid: |
1063 if p1 == sha1nodeconstants.nullid: |
1059 p1rev = nullrev |
1064 p1rev = nullrev |
1060 else: |
1065 else: |
1061 p1rev = self._nodetorev[p1] |
1066 p1rev = self._nodetorev[p1] |
1062 |
1067 |
1063 if p2 == nullid: |
1068 if p2 == sha1nodeconstants.nullid: |
1064 p2rev = nullrev |
1069 p2rev = nullrev |
1065 else: |
1070 else: |
1066 p2rev = self._nodetorev[p2] |
1071 p2rev = self._nodetorev[p2] |
1067 |
1072 |
1068 rid = self._db.execute( |
1073 rid = self._db.execute( |