##// END OF EJS Templates
tests: Add `--rhg` and `--with-rhg=<path>` options for `run-tests.py`...
tests: Add `--rhg` and `--with-rhg=<path>` options for `run-tests.py` They are mostly equivalent to the corresponding `chg` options. For now, many tests are still failing in this configuration. It is *not* run on CI. Differential Revision: https://phab.mercurial-scm.org/D10095

File last commit:

r47343:755c31a1 default
r47426:fb236859 default
Show More
parsers.rs
508 lines | 16.6 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;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 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-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 use std::time::Duration;
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
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 pub fn parse_dirstate(mut contents: &[u8]) -> Result<ParseResult, HgError> {
let mut copies = Vec::new();
let mut entries = Vec::new();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
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"),
);
if let Some(copy_source) = iter.next() {
copies.push((path, HgPath::new(copy_source)));
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 entries.push((path, entry));
contents = rest;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 Ok((parents, entries, copies))
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 /// `now` is the duration in seconds since the Unix epoch
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 #[cfg(not(feature = "dirstate-tree"))]
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,
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 now: Duration,
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.
let now: i32 = now.as_secs().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, _)| {
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 let mut length = MIN_ENTRY_SIZE + filename.len();
Yuya Nishihara
rust-dirstate: remove unneeded "ref"...
r43062 if let Some(copy) = copy_map.get(filename) {
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 length += copy.len() + 1;
}
length
})
.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() {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 let new_filename = filename.to_owned();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 let mut new_mtime: i32 = entry.mtime;
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 if entry.state == EntryState::Normal && entry.mtime == now {
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 // 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.
new_mtime = -1;
Raphaël Gomès
rust-parsers: use in-place mutation instead of allocating a new `Vec`...
r46223 *entry = DirstateEntry {
mtime: new_mtime,
..*entry
};
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 let mut new_filename = new_filename.into_vec();
Yuya Nishihara
rust-dirstate: remove unneeded "ref"...
r43062 if let Some(copy) = copy_map.get(filename) {
Raphaël Gomès
rust: do a clippy pass...
r45500 new_filename.push(b'\0');
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 new_filename.extend(copy.bytes());
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
Simon Sapin
rust: Replace DirstatePackError with HgError...
r47168 // 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>(new_mtime).unwrap();
packed
.write_i32::<BigEndian>(new_filename.len() as i32)
.unwrap();
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 packed.extend(new_filename)
}
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 }
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 /// `now` is the duration in seconds since the Unix epoch
#[cfg(feature = "dirstate-tree")]
pub fn pack_dirstate(
state_map: &mut StateMap,
copy_map: &CopyMap,
parents: DirstateParents,
now: Duration,
) -> Result<Vec<u8>, DirstatePackError> {
// TODO move away from i32 before 2038.
let now: i32 = now.as_secs().try_into().expect("time overflow");
let expected_size: usize = state_map
.iter()
.map(|(filename, _)| {
let mut length = MIN_ENTRY_SIZE + filename.len();
if let Some(copy) = copy_map.get(&filename) {
length += copy.len() + 1;
}
length
})
.sum();
let expected_size = expected_size + PARENT_SIZE * 2;
let mut packed = Vec::with_capacity(expected_size);
let mut new_state_map = vec![];
packed.extend(&parents.p1);
packed.extend(&parents.p2);
for (filename, entry) in state_map.iter() {
let new_filename = filename.to_owned();
let mut new_mtime: i32 = entry.mtime;
if entry.state == EntryState::Normal && entry.mtime == now {
// 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.
new_mtime = -1;
new_state_map.push((
filename.to_owned(),
DirstateEntry {
mtime: new_mtime,
..entry
},
));
}
let mut new_filename = new_filename.into_vec();
if let Some(copy) = copy_map.get(&filename) {
new_filename.push(b'\0');
new_filename.extend(copy.bytes());
}
packed.write_u8(entry.state.into())?;
packed.write_i32::<BigEndian>(entry.mode)?;
packed.write_i32::<BigEndian>(entry.size)?;
packed.write_i32::<BigEndian>(new_mtime)?;
packed.write_i32::<BigEndian>(new_filename.len() as i32)?;
packed.extend(new_filename)
}
if packed.len() != expected_size {
return Err(DirstatePackError::BadSize(expected_size, packed.len()));
}
state_map.extend(new_state_map);
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 };
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let now = Duration::new(15000000, 0);
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 };
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let now = Duration::new(15000000, 0);
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 };
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let now = Duration::new(15000000, 0);
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 };
let now = Duration::new(15000000, 0);
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 };
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let now = Duration::new(15000000, 0);
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 };
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let now = Duration::new(15000000, 0);
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 )
}
}