rust-revlog: teach the revlog opening code to read the repo options
This will become necessary as we start writing revlog data from Rust.
--- a/mercurial/revlog.py Tue Jun 27 17:34:51 2023 +0200
+++ b/mercurial/revlog.py Mon Sep 18 17:11:11 2023 +0200
@@ -16,6 +16,7 @@
import binascii
import collections
import contextlib
+import functools
import io
import os
import struct
@@ -224,9 +225,9 @@
parse_index_v1_nodemap = None
-def parse_index_v1_mixed(data, inline):
+def parse_index_v1_mixed(data, inline, default_header):
index, cache = parse_index_v1(data, inline)
- return rustrevlog.MixedIndex(index, data), cache
+ return rustrevlog.MixedIndex(index, data, default_header), cache
# corresponds to uncompressed length of indexformatng (2 gigs, 4-byte
@@ -1694,7 +1695,9 @@
elif devel_nodemap:
self._parse_index = parse_index_v1_nodemap
elif use_rust_index:
- self._parse_index = parse_index_v1_mixed
+ self._parse_index = functools.partial(
+ parse_index_v1_mixed, default_header=new_header
+ )
try:
d = self._parse_index(index_data, self._inline)
index, chunkcache = d
--- a/rust/hg-core/src/operations/debugdata.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/hg-core/src/operations/debugdata.rs Mon Sep 18 17:11:11 2023 +0200
@@ -6,11 +6,10 @@
// GNU General Public License version 2 or any later version.
use crate::repo::Repo;
-use crate::requirements;
use crate::revlog::{Revlog, RevlogError};
/// Kind of data to debug
-#[derive(Debug, Copy, Clone)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum DebugDataKind {
Changelog,
Manifest,
@@ -26,11 +25,12 @@
DebugDataKind::Changelog => "00changelog.i",
DebugDataKind::Manifest => "00manifest.i",
};
- let use_nodemap = repo
- .requirements()
- .contains(requirements::NODEMAP_REQUIREMENT);
- let revlog =
- Revlog::open(&repo.store_vfs(), index_file, None, use_nodemap)?;
+ let revlog = Revlog::open(
+ &repo.store_vfs(),
+ index_file,
+ None,
+ repo.default_revlog_options(kind == DebugDataKind::Changelog)?,
+ )?;
let rev =
crate::revset::resolve_rev_number_or_hex_prefix(revset, &revlog)?;
let data = revlog.get_rev_data_for_checked_rev(rev)?;
--- a/rust/hg-core/src/repo.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/hg-core/src/repo.rs Mon Sep 18 17:11:11 2023 +0200
@@ -8,6 +8,10 @@
use crate::errors::{HgError, IoResultExt};
use crate::lock::{try_with_lock_no_wait, LockError};
use crate::manifest::{Manifest, Manifestlog};
+use crate::requirements::{
+ CHANGELOGV2_REQUIREMENT, GENERALDELTA_REQUIREMENT, NODEMAP_REQUIREMENT,
+ REVLOGV1_REQUIREMENT, REVLOGV2_REQUIREMENT,
+};
use crate::revlog::filelog::Filelog;
use crate::revlog::RevlogError;
use crate::utils::debug::debug_wait_for_file_or_print;
@@ -15,8 +19,10 @@
use crate::utils::hg_path::HgPath;
use crate::utils::SliceExt;
use crate::vfs::{is_dir, is_file, Vfs};
-use crate::DirstateError;
-use crate::{requirements, NodePrefix, UncheckedRevision};
+use crate::{
+ requirements, NodePrefix, RevlogVersionOptions, UncheckedRevision,
+};
+use crate::{DirstateError, RevlogOpenOptions};
use std::cell::{Ref, RefCell, RefMut};
use std::collections::HashSet;
use std::io::Seek;
@@ -523,7 +529,7 @@
}
fn new_changelog(&self) -> Result<Changelog, HgError> {
- Changelog::open(&self.store_vfs(), self.has_nodemap())
+ Changelog::open(&self.store_vfs(), self.default_revlog_options(true)?)
}
pub fn changelog(&self) -> Result<Ref<Changelog>, HgError> {
@@ -535,7 +541,10 @@
}
fn new_manifestlog(&self) -> Result<Manifestlog, HgError> {
- Manifestlog::open(&self.store_vfs(), self.has_nodemap())
+ Manifestlog::open(
+ &self.store_vfs(),
+ self.default_revlog_options(false)?,
+ )
}
pub fn manifestlog(&self) -> Result<Ref<Manifestlog>, HgError> {
@@ -581,7 +590,7 @@
}
pub fn filelog(&self, path: &HgPath) -> Result<Filelog, HgError> {
- Filelog::open(self, path)
+ Filelog::open(self, path, self.default_revlog_options(false)?)
}
/// Write to disk any updates that were made through `dirstate_map_mut`.
@@ -730,6 +739,35 @@
}
Ok(())
}
+
+ pub fn default_revlog_options(
+ &self,
+ changelog: bool,
+ ) -> Result<RevlogOpenOptions, HgError> {
+ let requirements = self.requirements();
+ let version = if changelog
+ && requirements.contains(CHANGELOGV2_REQUIREMENT)
+ {
+ let compute_rank = self
+ .config()
+ .get_bool(b"experimental", b"changelog-v2.compute-rank")?;
+ RevlogVersionOptions::ChangelogV2 { compute_rank }
+ } else if requirements.contains(REVLOGV2_REQUIREMENT) {
+ RevlogVersionOptions::V2
+ } else if requirements.contains(REVLOGV1_REQUIREMENT) {
+ RevlogVersionOptions::V1 {
+ generaldelta: requirements.contains(GENERALDELTA_REQUIREMENT),
+ }
+ } else {
+ RevlogVersionOptions::V0
+ };
+ Ok(RevlogOpenOptions {
+ version,
+ // We don't need to dance around the slow path like in the Python
+ // implementation since we know we have access to the fast code.
+ use_nodemap: requirements.contains(NODEMAP_REQUIREMENT),
+ })
+ }
}
/// Lazily-initialized component of `Repo` with interior mutability
--- a/rust/hg-core/src/requirements.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/hg-core/src/requirements.rs Mon Sep 18 17:11:11 2023 +0200
@@ -77,7 +77,7 @@
/// rhg supports repository with or without these
const SUPPORTED: &[&str] = &[
- "generaldelta",
+ GENERALDELTA_REQUIREMENT,
SHARED_REQUIREMENT,
SHARESAFE_REQUIREMENT,
SPARSEREVLOG_REQUIREMENT,
@@ -100,6 +100,7 @@
// Copied from mercurial/requirements.py:
pub const DIRSTATE_V2_REQUIREMENT: &str = "dirstate-v2";
+pub const GENERALDELTA_REQUIREMENT: &str = "generaldelta";
/// A repository that uses the tracked hint dirstate file
#[allow(unused)]
@@ -128,11 +129,20 @@
#[allow(unused)]
pub const TREEMANIFEST_REQUIREMENT: &str = "treemanifest";
+/// Whether to use the "RevlogNG" or V1 of the revlog format
+#[allow(unused)]
+pub const REVLOGV1_REQUIREMENT: &str = "revlogv1";
+
/// Increment the sub-version when the revlog v2 format changes to lock out old
/// clients.
#[allow(unused)]
pub const REVLOGV2_REQUIREMENT: &str = "exp-revlogv2.1";
+/// Increment the sub-version when the revlog v2 format changes to lock out old
+/// clients.
+#[allow(unused)]
+pub const CHANGELOGV2_REQUIREMENT: &str = "exp-changelog-v2";
+
/// A repository with the sparserevlog feature will have delta chains that
/// can spread over a larger span. Sparse reading cuts these large spans into
/// pieces, so that each piece isn't too big.
--- a/rust/hg-core/src/revlog/changelog.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/hg-core/src/revlog/changelog.rs Mon Sep 18 17:11:11 2023 +0200
@@ -4,7 +4,7 @@
use crate::revlog::{Revlog, RevlogEntry, RevlogError};
use crate::utils::hg_path::HgPath;
use crate::vfs::Vfs;
-use crate::{Graph, GraphError, UncheckedRevision};
+use crate::{Graph, GraphError, RevlogOpenOptions, UncheckedRevision};
use itertools::Itertools;
use std::ascii::escape_default;
use std::borrow::Cow;
@@ -18,9 +18,11 @@
impl Changelog {
/// Open the `changelog` of a repository given by its root.
- pub fn open(store_vfs: &Vfs, use_nodemap: bool) -> Result<Self, HgError> {
- let revlog =
- Revlog::open(store_vfs, "00changelog.i", None, use_nodemap)?;
+ pub fn open(
+ store_vfs: &Vfs,
+ options: RevlogOpenOptions,
+ ) -> Result<Self, HgError> {
+ let revlog = Revlog::open(store_vfs, "00changelog.i", None, options)?;
Ok(Self { revlog })
}
@@ -342,7 +344,9 @@
let temp = tempfile::tempdir().unwrap();
let vfs = Vfs { base: temp.path() };
std::fs::write(temp.path().join("foo.i"), b"").unwrap();
- let revlog = Revlog::open(&vfs, "foo.i", None, false).unwrap();
+ let revlog =
+ Revlog::open(&vfs, "foo.i", None, RevlogOpenOptions::new())
+ .unwrap();
let changelog = Changelog { revlog };
assert_eq!(
--- a/rust/hg-core/src/revlog/filelog.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/hg-core/src/revlog/filelog.rs Mon Sep 18 17:11:11 2023 +0200
@@ -11,6 +11,7 @@
use crate::utils::SliceExt;
use crate::Graph;
use crate::GraphError;
+use crate::RevlogOpenOptions;
use crate::UncheckedRevision;
use std::path::PathBuf;
@@ -30,16 +31,21 @@
pub fn open_vfs(
store_vfs: &crate::vfs::Vfs<'_>,
file_path: &HgPath,
+ options: RevlogOpenOptions,
) -> Result<Self, HgError> {
let index_path = store_path(file_path, b".i");
let data_path = store_path(file_path, b".d");
let revlog =
- Revlog::open(store_vfs, index_path, Some(&data_path), false)?;
+ Revlog::open(store_vfs, index_path, Some(&data_path), options)?;
Ok(Self { revlog })
}
- pub fn open(repo: &Repo, file_path: &HgPath) -> Result<Self, HgError> {
- Self::open_vfs(&repo.store_vfs(), file_path)
+ pub fn open(
+ repo: &Repo,
+ file_path: &HgPath,
+ options: RevlogOpenOptions,
+ ) -> Result<Self, HgError> {
+ Self::open_vfs(&repo.store_vfs(), file_path, options)
}
/// The given node ID is that of the file as found in a filelog, not of a
--- a/rust/hg-core/src/revlog/index.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/hg-core/src/revlog/index.rs Mon Sep 18 17:11:11 2023 +0200
@@ -15,7 +15,7 @@
pub const COMPRESSION_MODE_INLINE: u8 = 2;
pub struct IndexHeader {
- header_bytes: [u8; 4],
+ pub(super) header_bytes: [u8; 4],
}
#[derive(Copy, Clone)]
@@ -54,32 +54,22 @@
BigEndian::read_u16(&self.header_bytes[2..4])
}
- const EMPTY_INDEX_HEADER: IndexHeader = IndexHeader {
- // We treat an empty file as a valid index with no entries.
- // Here we make an arbitrary choice of what we assume the format of the
- // index to be (V1, using generaldelta).
- // This doesn't matter too much, since we're only doing read-only
- // access. but the value corresponds to the `new_header` variable in
- // `revlog.py`, `_loadindex`
- header_bytes: [0, 3, 0, 1],
- };
-
- fn parse(index_bytes: &[u8]) -> Result<IndexHeader, HgError> {
+ pub fn parse(index_bytes: &[u8]) -> Result<Option<IndexHeader>, HgError> {
if index_bytes.is_empty() {
- return Ok(IndexHeader::EMPTY_INDEX_HEADER);
+ return Ok(None);
}
if index_bytes.len() < 4 {
return Err(HgError::corrupted(
"corrupted revlog: can't read the index format header",
));
}
- Ok(IndexHeader {
+ Ok(Some(IndexHeader {
header_bytes: {
let bytes: [u8; 4] =
index_bytes[0..4].try_into().expect("impossible");
bytes
},
- })
+ }))
}
}
@@ -239,8 +229,10 @@
/// Calculate the start of each entry when is_inline is true.
pub fn new(
bytes: Box<dyn Deref<Target = [u8]> + Send>,
+ default_header: IndexHeader,
) -> Result<Self, HgError> {
- let header = IndexHeader::parse(bytes.as_ref())?;
+ let header =
+ IndexHeader::parse(bytes.as_ref())?.unwrap_or(default_header);
if header.format_version() != IndexHeader::REVLOGV1 {
// A proper new version should have had a repo/store
@@ -598,6 +590,7 @@
pub fn is_inline(index_bytes: &[u8]) -> bool {
IndexHeader::parse(index_bytes)
.expect("too short")
+ .unwrap()
.format_flags()
.is_inline()
}
@@ -605,6 +598,7 @@
pub fn uses_generaldelta(index_bytes: &[u8]) -> bool {
IndexHeader::parse(index_bytes)
.expect("too short")
+ .unwrap()
.format_flags()
.uses_generaldelta()
}
@@ -612,6 +606,7 @@
pub fn get_version(index_bytes: &[u8]) -> u16 {
IndexHeader::parse(index_bytes)
.expect("too short")
+ .unwrap()
.format_version()
}
--- a/rust/hg-core/src/revlog/manifest.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/hg-core/src/revlog/manifest.rs Mon Sep 18 17:11:11 2023 +0200
@@ -4,12 +4,14 @@
use crate::utils::hg_path::HgPath;
use crate::utils::SliceExt;
use crate::vfs::Vfs;
-use crate::{Graph, GraphError, Revision, UncheckedRevision};
+use crate::{
+ Graph, GraphError, Revision, RevlogOpenOptions, UncheckedRevision,
+};
/// A specialized `Revlog` to work with `manifest` data format.
pub struct Manifestlog {
/// The generic `revlog` format.
- revlog: Revlog,
+ pub(crate) revlog: Revlog,
}
impl Graph for Manifestlog {
@@ -20,9 +22,11 @@
impl Manifestlog {
/// Open the `manifest` of a repository given by its root.
- pub fn open(store_vfs: &Vfs, use_nodemap: bool) -> Result<Self, HgError> {
- let revlog =
- Revlog::open(store_vfs, "00manifest.i", None, use_nodemap)?;
+ pub fn open(
+ store_vfs: &Vfs,
+ options: RevlogOpenOptions,
+ ) -> Result<Self, HgError> {
+ let revlog = Revlog::open(store_vfs, "00manifest.i", None, options)?;
Ok(Self { revlog })
}
--- a/rust/hg-core/src/revlog/mod.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/hg-core/src/revlog/mod.rs Mon Sep 18 17:11:11 2023 +0200
@@ -225,6 +225,55 @@
}
}
+#[derive(Debug, Copy, Clone)]
+pub enum RevlogVersionOptions {
+ V0,
+ V1 { generaldelta: bool },
+ V2,
+ ChangelogV2 { compute_rank: bool },
+}
+
+/// Options to govern how a revlog should be opened, usually from the
+/// repository configuration or requirements.
+#[derive(Debug, Copy, Clone)]
+pub struct RevlogOpenOptions {
+ /// The revlog version, along with any option specific to this version
+ pub version: RevlogVersionOptions,
+ /// Whether the revlog uses a persistent nodemap.
+ pub use_nodemap: bool,
+ // TODO other non-header/version options,
+}
+
+impl RevlogOpenOptions {
+ pub fn new() -> Self {
+ Self {
+ version: RevlogVersionOptions::V1 { generaldelta: true },
+ use_nodemap: false,
+ }
+ }
+
+ fn default_index_header(&self) -> index::IndexHeader {
+ index::IndexHeader {
+ header_bytes: match self.version {
+ RevlogVersionOptions::V0 => [0, 0, 0, 0],
+ RevlogVersionOptions::V1 { generaldelta } => {
+ [0, if generaldelta { 3 } else { 1 }, 0, 1]
+ }
+ RevlogVersionOptions::V2 => 0xDEADu32.to_be_bytes(),
+ RevlogVersionOptions::ChangelogV2 { compute_rank: _ } => {
+ 0xD34Du32.to_be_bytes()
+ }
+ },
+ }
+ }
+}
+
+impl Default for RevlogOpenOptions {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
impl Revlog {
/// Open a revlog index file.
///
@@ -234,24 +283,30 @@
store_vfs: &Vfs,
index_path: impl AsRef<Path>,
data_path: Option<&Path>,
- use_nodemap: bool,
+ options: RevlogOpenOptions,
) -> Result<Self, HgError> {
- Self::open_gen(store_vfs, index_path, data_path, use_nodemap, None)
+ Self::open_gen(store_vfs, index_path, data_path, options, None)
}
fn open_gen(
store_vfs: &Vfs,
index_path: impl AsRef<Path>,
data_path: Option<&Path>,
- use_nodemap: bool,
+ options: RevlogOpenOptions,
nodemap_for_test: Option<nodemap::NodeTree>,
) -> Result<Self, HgError> {
let index_path = index_path.as_ref();
let index = {
match store_vfs.mmap_open_opt(index_path)? {
- None => Index::new(Box::<Vec<_>>::default()),
+ None => Index::new(
+ Box::<Vec<_>>::default(),
+ options.default_index_header(),
+ ),
Some(index_mmap) => {
- let index = Index::new(Box::new(index_mmap))?;
+ let index = Index::new(
+ Box::new(index_mmap),
+ options.default_index_header(),
+ )?;
Ok(index)
}
}
@@ -270,7 +325,7 @@
Some(Box::new(data_mmap))
};
- let nodemap = if index.is_inline() || !use_nodemap {
+ let nodemap = if index.is_inline() || !options.use_nodemap {
None
} else {
NodeMapDocket::read_from_file(store_vfs, index_path)?.map(
@@ -809,7 +864,9 @@
let temp = tempfile::tempdir().unwrap();
let vfs = Vfs { base: temp.path() };
std::fs::write(temp.path().join("foo.i"), b"").unwrap();
- let revlog = Revlog::open(&vfs, "foo.i", None, false).unwrap();
+ let revlog =
+ Revlog::open(&vfs, "foo.i", None, RevlogOpenOptions::new())
+ .unwrap();
assert!(revlog.is_empty());
assert_eq!(revlog.len(), 0);
assert!(revlog.get_entry(0.into()).is_err());
@@ -855,7 +912,9 @@
.flatten()
.collect_vec();
std::fs::write(temp.path().join("foo.i"), contents).unwrap();
- let revlog = Revlog::open(&vfs, "foo.i", None, false).unwrap();
+ let revlog =
+ Revlog::open(&vfs, "foo.i", None, RevlogOpenOptions::new())
+ .unwrap();
let entry0 = revlog.get_entry(0.into()).ok().unwrap();
assert_eq!(entry0.revision(), Revision(0));
@@ -926,8 +985,14 @@
idx.insert_node(Revision(0), node0).unwrap();
idx.insert_node(Revision(1), node1).unwrap();
- let revlog =
- Revlog::open_gen(&vfs, "foo.i", None, true, Some(idx.nt)).unwrap();
+ let revlog = Revlog::open_gen(
+ &vfs,
+ "foo.i",
+ None,
+ RevlogOpenOptions::new(),
+ Some(idx.nt),
+ )
+ .unwrap();
// accessing the data shows the corruption
revlog.get_entry(0.into()).unwrap().data().unwrap_err();
--- a/rust/hg-cpython/src/revlog.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/hg-cpython/src/revlog.rs Mon Sep 18 17:11:11 2023 +0200
@@ -17,6 +17,7 @@
PyObject, PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject,
};
use hg::{
+ index::IndexHeader,
nodemap::{Block, NodeMapError, NodeTree},
revlog::{nodemap::NodeMap, NodePrefix, RevlogIndex},
BaseRevision, Revision, UncheckedRevision,
@@ -47,9 +48,10 @@
def __new__(
_cls,
cindex: PyObject,
- data: PyObject
+ data: PyObject,
+ default_header: u32,
) -> PyResult<MixedIndex> {
- Self::new(py, cindex, data)
+ Self::new(py, cindex, data, default_header)
}
/// Compatibility layer used for Python consumers needing access to the C index
@@ -364,6 +366,7 @@
py: Python,
cindex: PyObject,
data: PyObject,
+ header: u32,
) -> PyResult<MixedIndex> {
// Safety: we keep the buffer around inside the class as `index_mmap`
let (buf, bytes) = unsafe { mmap_keeparound(py, data)? };
@@ -371,7 +374,15 @@
Self::create_instance(
py,
RefCell::new(cindex::Index::new(py, cindex)?),
- RefCell::new(hg::index::Index::new(bytes).unwrap()),
+ RefCell::new(
+ hg::index::Index::new(
+ bytes,
+ IndexHeader::parse(&header.to_be_bytes())
+ .expect("default header is broken")
+ .unwrap(),
+ )
+ .unwrap(),
+ ),
RefCell::new(None),
RefCell::new(None),
RefCell::new(None),
--- a/rust/rhg/src/commands/status.rs Tue Jun 27 17:34:51 2023 +0200
+++ b/rust/rhg/src/commands/status.rs Mon Sep 18 17:11:11 2023 +0200
@@ -28,12 +28,12 @@
get_bytes_from_os_str, get_bytes_from_os_string, get_path_from_bytes,
};
use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
-use hg::DirstateStatus;
use hg::PatternFileWarning;
use hg::Revision;
use hg::StatusError;
use hg::StatusOptions;
use hg::{self, narrow, sparse};
+use hg::{DirstateStatus, RevlogOpenOptions};
use log::info;
use rayon::prelude::*;
use std::borrow::Cow;
@@ -383,6 +383,7 @@
})?;
let working_directory_vfs = repo.working_directory_vfs();
let store_vfs = repo.store_vfs();
+ let revlog_open_options = repo.default_revlog_options(false)?;
let res: Vec<_> = take(&mut ds_status.unsure)
.into_par_iter()
.map(|to_check| {
@@ -396,6 +397,7 @@
check_exec,
&manifest,
&to_check.path,
+ revlog_open_options,
) {
Err(HgError::IoError { .. }) => {
// IO errors most likely stem from the file being
@@ -747,6 +749,7 @@
check_exec: bool,
manifest: &Manifest,
hg_path: &HgPath,
+ revlog_open_options: RevlogOpenOptions,
) -> Result<UnsureOutcome, HgError> {
let vfs = working_directory_vfs;
let fs_path = hg_path_to_path_buf(hg_path).expect("HgPath conversion");
@@ -778,7 +781,11 @@
if entry_flags != fs_flags {
return Ok(UnsureOutcome::Modified);
}
- let filelog = hg::filelog::Filelog::open_vfs(&store_vfs, hg_path)?;
+ let filelog = hg::filelog::Filelog::open_vfs(
+ &store_vfs,
+ hg_path,
+ revlog_open_options,
+ )?;
let fs_len = fs_metadata.len();
let file_node = entry.node_id()?;
let filelog_entry = filelog.entry_for_node(file_node).map_err(|_| {
--- a/tests/test-rust-revlog.py Tue Jun 27 17:34:51 2023 +0200
+++ b/tests/test-rust-revlog.py Mon Sep 18 17:11:11 2023 +0200
@@ -1,3 +1,4 @@
+import struct
import unittest
try:
@@ -14,6 +15,8 @@
from mercurial.testing import revlog as revlogtesting
+header = struct.unpack(">I", revlogtesting.data_non_inlined[:4])[0]
+
@unittest.skipIf(
rustext is None,
@@ -22,24 +25,24 @@
class RustRevlogIndexTest(revlogtesting.RevlogBasedTestBase):
def test_heads(self):
idx = self.parseindex()
- rustidx = revlog.MixedIndex(idx, revlogtesting.data_non_inlined)
+ rustidx = revlog.MixedIndex(idx, revlogtesting.data_non_inlined, header)
self.assertEqual(rustidx.headrevs(), idx.headrevs())
def test_get_cindex(self):
# drop me once we no longer need the method for shortest node
idx = self.parseindex()
- rustidx = revlog.MixedIndex(idx, revlogtesting.data_non_inlined)
+ rustidx = revlog.MixedIndex(idx, revlogtesting.data_non_inlined, header)
cidx = rustidx.get_cindex()
self.assertTrue(idx is cidx)
def test_len(self):
idx = self.parseindex()
- rustidx = revlog.MixedIndex(idx, revlogtesting.data_non_inlined)
+ rustidx = revlog.MixedIndex(idx, revlogtesting.data_non_inlined, header)
self.assertEqual(len(rustidx), len(idx))
def test_ancestors(self):
idx = self.parseindex()
- rustidx = revlog.MixedIndex(idx, revlogtesting.data_non_inlined)
+ rustidx = revlog.MixedIndex(idx, revlogtesting.data_non_inlined, header)
lazy = LazyAncestors(rustidx, [3], 0, True)
# we have two more references to the index:
# - in its inner iterator for __contains__ and __bool__