##// END OF EJS Templates
revlog: update data file record before index rename...
revlog: update data file record before index rename When migrating from inline to non-inline data storage, the data file is recorded initially as zero sized so that it is removed on failure. But the record has to be updated before the index is renamed, otherwise data is lost on rollback. Differential Revision: https://phab.mercurial-scm.org/D10725

File last commit:

r47894:cd8ca38f default
r48065:46b828b8 default
Show More
parsers.rs
478 lines | 14.8 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
Simon Sapin
rust: Replace DirstatePackError with HgError...
r47168 use crate::errors::HgError;
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 use crate::utils::hg_path::HgPath;
Raphaël Gomès
rust: switch hg-core and hg-cpython to rust 2018 edition...
r42828 use crate::{
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 dirstate::{CopyMap, EntryState, RawEntry, StateMap},
Simon Sapin
rust: Remove DirstateParseError and ListDirstateTrackedFilesError...
r47169 DirstateEntry, DirstateParents,
Raphaël Gomès
rust: switch hg-core and hg-cpython to rust 2018 edition...
r42828 };
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 use byteorder::{BigEndian, WriteBytesExt};
use bytes_cast::BytesCast;
Raphaël Gomès
hg-core: add function timing information...
r45028 use micro_timer::timed;
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 use std::convert::{TryFrom, TryInto};
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
/// Parents are stored in the dirstate as byte hashes.
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 pub const PARENT_SIZE: usize = 20;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 /// Dirstate entries have a static part of 8 + 32 + 32 + 32 + 32 bits.
const MIN_ENTRY_SIZE: usize = 17;
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 type ParseResult<'a> = (
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 &'a DirstateParents,
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 Vec<(&'a HgPath, DirstateEntry)>,
Vec<(&'a HgPath, &'a HgPath)>,
);
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993
Simon Sapin
rhg: Add support for the blackbox extension...
r47343 pub fn parse_dirstate_parents(
contents: &[u8],
) -> Result<&DirstateParents, HgError> {
let (parents, _rest) = DirstateParents::from_bytes(contents)
.map_err(|_| HgError::corrupted("Too little data for dirstate."))?;
Ok(parents)
}
Raphaël Gomès
hg-core: add function timing information...
r45028 #[timed]
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 pub fn parse_dirstate(contents: &[u8]) -> Result<ParseResult, HgError> {
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 let mut copies = Vec::new();
let mut entries = Vec::new();
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 let parents =
parse_dirstate_entries(contents, |path, entry, copy_source| {
if let Some(source) = copy_source {
copies.push((path, source));
}
entries.push((path, *entry));
})?;
Ok((parents, entries, copies))
}
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 pub fn parse_dirstate_entries<'a>(
mut contents: &'a [u8],
mut each_entry: impl FnMut(&'a HgPath, &DirstateEntry, Option<&'a HgPath>),
) -> Result<&'a DirstateParents, HgError> {
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 let (parents, rest) = DirstateParents::from_bytes(contents)
.map_err(|_| HgError::corrupted("Too little data for dirstate."))?;
contents = rest;
while !contents.is_empty() {
let (raw_entry, rest) = RawEntry::from_bytes(contents)
.map_err(|_| HgError::corrupted("Overflow in dirstate."))?;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 let entry = DirstateEntry {
state: EntryState::try_from(raw_entry.state)?,
mode: raw_entry.mode.get(),
mtime: raw_entry.mtime.get(),
size: raw_entry.size.get(),
};
let (paths, rest) =
u8::slice_from_bytes(rest, raw_entry.length.get() as usize)
.map_err(|_| HgError::corrupted("Overflow in dirstate."))?;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 // `paths` is either a single path, or two paths separated by a NULL
// byte
let mut iter = paths.splitn(2, |&byte| byte == b'\0');
let path = HgPath::new(
iter.next().expect("splitn always yields at least one item"),
);
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 let copy_source = iter.next().map(HgPath::new);
each_entry(path, &entry, copy_source);
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 contents = rest;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 Ok(parents)
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 fn packed_filename_and_copy_source_size(
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 filename: &HgPath,
copy_source: Option<&HgPath>,
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 ) -> usize {
filename.len()
+ if let Some(source) = copy_source {
b"\0".len() + source.len()
} else {
0
}
}
pub fn packed_entry_size(
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 filename: &HgPath,
copy_source: Option<&HgPath>,
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 ) -> usize {
MIN_ENTRY_SIZE
+ packed_filename_and_copy_source_size(filename, copy_source)
}
pub fn pack_entry(
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 filename: &HgPath,
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 entry: &DirstateEntry,
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 copy_source: Option<&HgPath>,
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 packed: &mut Vec<u8>,
) {
let length = packed_filename_and_copy_source_size(filename, copy_source);
// Unwrapping because `impl std::io::Write for Vec<u8>` never errors
packed.write_u8(entry.state.into()).unwrap();
packed.write_i32::<BigEndian>(entry.mode).unwrap();
packed.write_i32::<BigEndian>(entry.size).unwrap();
packed.write_i32::<BigEndian>(entry.mtime).unwrap();
packed.write_i32::<BigEndian>(length as i32).unwrap();
packed.extend(filename.as_bytes());
if let Some(source) = copy_source {
packed.push(b'\0');
packed.extend(source.as_bytes());
}
}
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 /// Seconds since the Unix epoch
pub struct Timestamp(pub u64);
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 pub fn clear_ambiguous_mtime(
entry: &mut DirstateEntry,
mtime_now: i32,
) -> bool {
let ambiguous =
entry.state == EntryState::Normal && entry.mtime == mtime_now;
if ambiguous {
// The file was last modified "simultaneously" with the current
// write to dirstate (i.e. within the same second for file-
// systems with a granularity of 1 sec). This commonly happens
// for at least a couple of files on 'update'.
// The user could change the file without changing its size
// within the same second. Invalidate the file's mtime in
// dirstate, forcing future 'status' calls to compare the
// contents of the file if the size is the same. This prevents
// mistakenly treating such files as clean.
entry.mtime = -1;
}
ambiguous
}
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 pub fn pack_dirstate(
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 state_map: &mut StateMap,
copy_map: &CopyMap,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 parents: DirstateParents,
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 now: Timestamp,
Simon Sapin
rust: Replace DirstatePackError with HgError...
r47168 ) -> Result<Vec<u8>, HgError> {
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 // TODO move away from i32 before 2038.
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 let now: i32 = now.0.try_into().expect("time overflow");
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let expected_size: usize = state_map
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 .iter()
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 .map(|(filename, _)| {
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 packed_entry_size(filename, copy_map.get(filename).map(|p| &**p))
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 })
.sum();
let expected_size = expected_size + PARENT_SIZE * 2;
let mut packed = Vec::with_capacity(expected_size);
Simon Sapin
rust: Make `DirstateParents`’s fields typed `Node`s...
r47337 packed.extend(parents.p1.as_bytes());
packed.extend(parents.p2.as_bytes());
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Raphaël Gomès
rust-parsers: use in-place mutation instead of allocating a new `Vec`...
r46223 for (filename, entry) in state_map.iter_mut() {
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 clear_ambiguous_mtime(entry, now);
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 pack_entry(
filename,
entry,
copy_map.get(filename).map(|p| &**p),
&mut packed,
)
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
if packed.len() != expected_size {
Simon Sapin
rust: Replace DirstatePackError with HgError...
r47168 return Err(HgError::CorruptedRepository(format!(
"bad dirstate size: {} != {}",
expected_size,
packed.len()
)));
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 Ok(packed)
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
#[cfg(test)]
mod tests {
use super::*;
Raphaël Gomès
rust-performance: introduce FastHashMap type alias for HashMap...
r44278 use crate::{utils::hg_path::HgPathBuf, FastHashMap};
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 use pretty_assertions::assert_eq;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
#[test]
fn test_pack_dirstate_empty() {
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 let mut state_map = StateMap::default();
Raphaël Gomès
rust-performance: introduce FastHashMap type alias for HashMap...
r44278 let copymap = FastHashMap::default();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 let parents = DirstateParents {
Simon Sapin
rust: Make `DirstateParents`’s fields typed `Node`s...
r47337 p1: b"12345678910111213141".into(),
p2: b"00000000000000000000".into(),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 };
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 let now = Timestamp(15000000);
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let expected = b"1234567891011121314100000000000000000000".to_vec();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
assert_eq!(
expected,
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 pack_dirstate(&mut state_map, &copymap, parents, now).unwrap()
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 );
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993
assert!(state_map.is_empty())
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
#[test]
fn test_pack_dirstate_one_entry() {
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let expected_state_map: StateMap = [(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(b"f1"),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 DirstateEntry {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 state: EntryState::Normal,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 mode: 0o644,
size: 0,
mtime: 791231220,
},
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 )]
.iter()
.cloned()
.collect();
let mut state_map = expected_state_map.clone();
Raphaël Gomès
rust-performance: introduce FastHashMap type alias for HashMap...
r44278 let copymap = FastHashMap::default();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 let parents = DirstateParents {
Simon Sapin
rust: Make `DirstateParents`’s fields typed `Node`s...
r47337 p1: b"12345678910111213141".into(),
p2: b"00000000000000000000".into(),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 };
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 let now = Timestamp(15000000);
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let expected = [
49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49,
51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48, 110, 0, 0, 1, 164, 0, 0, 0, 0, 47,
41, 58, 244, 0, 0, 0, 2, 102, 49,
]
.to_vec();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
assert_eq!(
expected,
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 pack_dirstate(&mut state_map, &copymap, parents, now).unwrap()
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 );
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 assert_eq!(expected_state_map, state_map);
}
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 #[test]
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 fn test_pack_dirstate_one_entry_with_copy() {
let expected_state_map: StateMap = [(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(b"f1"),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 DirstateEntry {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 state: EntryState::Normal,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 mode: 0o644,
size: 0,
mtime: 791231220,
},
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 )]
.iter()
.cloned()
.collect();
let mut state_map = expected_state_map.clone();
Raphaël Gomès
rust-performance: introduce FastHashMap type alias for HashMap...
r44278 let mut copymap = FastHashMap::default();
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 copymap.insert(
HgPathBuf::from_bytes(b"f1"),
HgPathBuf::from_bytes(b"copyname"),
);
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 let parents = DirstateParents {
Simon Sapin
rust: Make `DirstateParents`’s fields typed `Node`s...
r47337 p1: b"12345678910111213141".into(),
p2: b"00000000000000000000".into(),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 };
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 let now = Timestamp(15000000);
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let expected = [
49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49,
51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48, 110, 0, 0, 1, 164, 0, 0, 0, 0, 47,
41, 58, 244, 0, 0, 0, 11, 102, 49, 0, 99, 111, 112, 121, 110, 97,
109, 101,
]
.to_vec();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
assert_eq!(
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 expected,
pack_dirstate(&mut state_map, &copymap, parents, now).unwrap()
);
assert_eq!(expected_state_map, state_map);
}
#[test]
fn test_parse_pack_one_entry_with_copy() {
let mut state_map: StateMap = [(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(b"f1"),
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 DirstateEntry {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 state: EntryState::Normal,
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 mode: 0o644,
size: 0,
mtime: 791231220,
},
)]
.iter()
.cloned()
.collect();
Raphaël Gomès
rust-performance: introduce FastHashMap type alias for HashMap...
r44278 let mut copymap = FastHashMap::default();
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 copymap.insert(
HgPathBuf::from_bytes(b"f1"),
HgPathBuf::from_bytes(b"copyname"),
);
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let parents = DirstateParents {
Simon Sapin
rust: Make `DirstateParents`’s fields typed `Node`s...
r47337 p1: b"12345678910111213141".into(),
p2: b"00000000000000000000".into(),
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 };
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 let now = Timestamp(15000000);
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let result =
pack_dirstate(&mut state_map, &copymap, parents.clone(), now)
.unwrap();
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 let (new_parents, entries, copies) =
parse_dirstate(result.as_slice()).unwrap();
let new_state_map: StateMap = entries
.into_iter()
.map(|(path, entry)| (path.to_owned(), entry))
.collect();
let new_copy_map: CopyMap = copies
.into_iter()
.map(|(path, copy)| (path.to_owned(), copy.to_owned()))
.collect();
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 assert_eq!(
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 (&parents, state_map, copymap),
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 (new_parents, new_state_map, new_copy_map)
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 )
}
#[test]
fn test_parse_pack_multiple_entries_with_copy() {
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let mut state_map: StateMap = [
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 (
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(b"f1"),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 DirstateEntry {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 state: EntryState::Normal,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 mode: 0o644,
size: 0,
mtime: 791231220,
},
),
(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(b"f2"),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 DirstateEntry {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 state: EntryState::Merged,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 mode: 0o777,
size: 1000,
mtime: 791231220,
},
),
(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(b"f3"),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 DirstateEntry {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 state: EntryState::Removed,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 mode: 0o644,
size: 234553,
mtime: 791231220,
},
),
(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(b"f4\xF6"),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 DirstateEntry {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 state: EntryState::Added,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 mode: 0o644,
size: -1,
mtime: -1,
},
),
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 ]
.iter()
.cloned()
.collect();
Raphaël Gomès
rust-performance: introduce FastHashMap type alias for HashMap...
r44278 let mut copymap = FastHashMap::default();
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 copymap.insert(
HgPathBuf::from_bytes(b"f1"),
HgPathBuf::from_bytes(b"copyname"),
);
copymap.insert(
HgPathBuf::from_bytes(b"f4\xF6"),
HgPathBuf::from_bytes(b"copyname2"),
);
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 let parents = DirstateParents {
Simon Sapin
rust: Make `DirstateParents`’s fields typed `Node`s...
r47337 p1: b"12345678910111213141".into(),
p2: b"00000000000000000000".into(),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 };
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 let now = Timestamp(15000000);
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 let result =
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 pack_dirstate(&mut state_map, &copymap, parents.clone(), now)
.unwrap();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 let (new_parents, entries, copies) =
parse_dirstate(result.as_slice()).unwrap();
let new_state_map: StateMap = entries
.into_iter()
.map(|(path, entry)| (path.to_owned(), entry))
.collect();
let new_copy_map: CopyMap = copies
.into_iter()
.map(|(path, copy)| (path.to_owned(), copy.to_owned()))
.collect();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 assert_eq!(
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 (&parents, state_map, copymap),
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 (new_parents, new_state_map, new_copy_map)
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 )
}
#[test]
/// https://www.mercurial-scm.org/repo/hg/rev/af3f26b6bba4
fn test_parse_pack_one_entry_with_copy_and_time_conflict() {
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let mut state_map: StateMap = [(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(b"f1"),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 DirstateEntry {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 state: EntryState::Normal,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 mode: 0o644,
size: 0,
mtime: 15000000,
},
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 )]
.iter()
.cloned()
.collect();
Raphaël Gomès
rust-performance: introduce FastHashMap type alias for HashMap...
r44278 let mut copymap = FastHashMap::default();
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 copymap.insert(
HgPathBuf::from_bytes(b"f1"),
HgPathBuf::from_bytes(b"copyname"),
);
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 let parents = DirstateParents {
Simon Sapin
rust: Make `DirstateParents`’s fields typed `Node`s...
r47337 p1: b"12345678910111213141".into(),
p2: b"00000000000000000000".into(),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 };
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 let now = Timestamp(15000000);
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 let result =
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 pack_dirstate(&mut state_map, &copymap, parents.clone(), now)
.unwrap();
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 let (new_parents, entries, copies) =
parse_dirstate(result.as_slice()).unwrap();
let new_state_map: StateMap = entries
.into_iter()
.map(|(path, entry)| (path.to_owned(), entry))
.collect();
let new_copy_map: CopyMap = copies
.into_iter()
.map(|(path, copy)| (path.to_owned(), copy.to_owned()))
.collect();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
assert_eq!(
(
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 &parents,
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 [(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(b"f1"),
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 DirstateEntry {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 state: EntryState::Normal,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 mode: 0o644,
size: 0,
mtime: -1
}
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 )]
.iter()
.cloned()
.collect::<StateMap>(),
copymap,
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 ),
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 (new_parents, new_state_map, new_copy_map)
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 )
}
}