Mercurial > hg
view rust/hg-core/src/revlog/changelog.rs @ 47964:796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
When `rhg status` cannot determine whether a file is clean based on mtime and
size alone, it needs to compare its contents with those found in the parent
commit. Previously, rhg would find the (same) manifest of that commit again
for every such file. This is lifted out of the loop and reused.
Differential Revision: https://phab.mercurial-scm.org/D11411
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 13 Sep 2021 18:09:10 +0200 |
parents | 001d747c2baf |
children | 6c653d9d41b8 |
line wrap: on
line source
use crate::errors::HgError; use crate::repo::Repo; use crate::revlog::revlog::{Revlog, RevlogError}; use crate::revlog::Revision; use crate::revlog::{Node, NodePrefix}; /// A specialized `Revlog` to work with `changelog` data format. pub struct Changelog { /// The generic `revlog` format. pub(crate) revlog: Revlog, } impl Changelog { /// Open the `changelog` of a repository given by its root. pub fn open(repo: &Repo) -> Result<Self, HgError> { let revlog = Revlog::open(repo, "00changelog.i", None)?; Ok(Self { revlog }) } /// Return the `ChangelogEntry` a given node id. pub fn get_node( &self, node: NodePrefix, ) -> Result<ChangelogEntry, RevlogError> { let rev = self.revlog.get_node_rev(node)?; self.get_rev(rev) } /// Return the `ChangelogEntry` of a given node revision. pub fn get_rev( &self, rev: Revision, ) -> Result<ChangelogEntry, RevlogError> { let bytes = self.revlog.get_rev_data(rev)?; Ok(ChangelogEntry { bytes }) } pub fn node_from_rev(&self, rev: Revision) -> Option<&Node> { Some(self.revlog.index.get_entry(rev)?.hash()) } } /// `Changelog` entry which knows how to interpret the `changelog` data bytes. #[derive(Debug)] pub struct ChangelogEntry { /// The data bytes of the `changelog` entry. bytes: Vec<u8>, } impl ChangelogEntry { /// Return an iterator over the lines of the entry. pub fn lines(&self) -> impl Iterator<Item = &[u8]> { self.bytes .split(|b| b == &b'\n') .filter(|line| !line.is_empty()) } /// Return the node id of the `manifest` referenced by this `changelog` /// entry. pub fn manifest_node(&self) -> Result<Node, HgError> { Node::from_hex_for_repo( self.lines() .next() .ok_or_else(|| HgError::corrupted("empty changelog entry"))?, ) } }