##// END OF EJS Templates
tags: validate nodes in _getfnodes() and update cache in case of unknown nodes...
tags: validate nodes in _getfnodes() and update cache in case of unknown nodes `hgtagsfnodescache` can contain unknown nodes due to cache corruption and this lead to a traceback on operations like `hg tags` as we don't validate nodes. This patch validates that all filenodes returned after `hgtagsfnodescache` are known to the repository. If there exists any unknown filenode, we force recompute it and update the cache. The test change demonstrates the fix. Differential Revision: https://phab.mercurial-scm.org/D10083

File last commit:

r47160:645ee722 default
r47402:9a31f653 default
Show More
manifest.rs
76 lines | 2.3 KiB | application/rls-services+xml | RustLexer
Simon Sapin
rust: introduce Repo and Vfs types for filesystem abstraction...
r46782 use crate::repo::Repo;
Antoine Cezar
hg-core: add `Manifest` a specialized `Revlog`...
r46104 use crate::revlog::revlog::{Revlog, RevlogError};
Simon Sapin
rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef...
r47160 use crate::revlog::NodePrefix;
Antoine Cezar
hg-core: add `Manifest` a specialized `Revlog`...
r46104 use crate::revlog::Revision;
use crate::utils::hg_path::HgPath;
/// A specialized `Revlog` to work with `manifest` data format.
pub struct Manifest {
/// The generic `revlog` format.
revlog: Revlog,
}
impl Manifest {
/// Open the `manifest` of a repository given by its root.
Simon Sapin
rust: introduce Repo and Vfs types for filesystem abstraction...
r46782 pub fn open(repo: &Repo) -> Result<Self, RevlogError> {
let revlog = Revlog::open(repo, "00manifest.i", None)?;
Antoine Cezar
hg-core: add `Manifest` a specialized `Revlog`...
r46104 Ok(Self { revlog })
}
/// Return the `ManifestEntry` of a given node id.
Simon Sapin
rust: use NodePrefix::from_hex instead of hex::decode directly...
r46647 pub fn get_node(
&self,
Simon Sapin
rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef...
r47160 node: NodePrefix,
Simon Sapin
rust: use NodePrefix::from_hex instead of hex::decode directly...
r46647 ) -> Result<ManifestEntry, RevlogError> {
Antoine Cezar
hg-core: add `Manifest` a specialized `Revlog`...
r46104 let rev = self.revlog.get_node_rev(node)?;
self.get_rev(rev)
}
/// Return the `ManifestEntry` of a given node revision.
pub fn get_rev(
&self,
rev: Revision,
) -> Result<ManifestEntry, RevlogError> {
let bytes = self.revlog.get_rev_data(rev)?;
Ok(ManifestEntry { bytes })
}
}
/// `Manifest` entry which knows how to interpret the `manifest` data bytes.
#[derive(Debug)]
pub struct ManifestEntry {
bytes: Vec<u8>,
}
impl ManifestEntry {
/// 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 an iterator over the files of the entry.
pub fn files(&self) -> impl Iterator<Item = &HgPath> {
self.lines().filter(|line| !line.is_empty()).map(|line| {
let pos = line
.iter()
.position(|x| x == &b'\0')
.expect("manifest line should contain \\0");
HgPath::new(&line[..pos])
})
}
Antoine Cezar
hg-core: add `files_with_nodes` to `Manifest`...
r46111
/// Return an iterator over the files of the entry.
pub fn files_with_nodes(&self) -> impl Iterator<Item = (&HgPath, &[u8])> {
self.lines().filter(|line| !line.is_empty()).map(|line| {
let pos = line
.iter()
.position(|x| x == &b'\0')
.expect("manifest line should contain \\0");
let hash_start = pos + 1;
let hash_end = hash_start + 40;
(HgPath::new(&line[..pos]), &line[hash_start..hash_end])
})
}
Antoine Cezar
hg-core: add `Manifest` a specialized `Revlog`...
r46104 }