manifest-tree: make Entry::from_elements sort input

Summary:
Take some extra effort to force the right order when serializing entries to
bytes. Previously the order happens to match `BTreeMap<PathComponentBuf, _>`
order. But that is problematic for git.

This also makes `lookup_hg` able to use fast path to skip for tests that do
not have elements sorted.

Reviewed By: markbt

Differential Revision: D33369605

fbshipit-source-id: e939cc2089be63b69ccd590870b28f7468cb35ed
This commit is contained in:
Jun Wu 2022-01-04 18:56:54 -08:00 committed by Facebook GitHub Bot
parent 5fcd060868
commit f62e6561d6
2 changed files with 5 additions and 4 deletions

View File

@ -8,7 +8,6 @@
mod diff;
mod iter;
mod link;
#[allow(unused)]
mod namecmp;
mod store;
#[cfg(any(test, feature = "for-tests"))]

View File

@ -121,7 +121,9 @@ impl Entry {
}
/// The primary builder of an Entry, from a list of `Element`.
pub fn from_elements(elements: Vec<Element>, format: TreeFormat) -> Entry {
pub fn from_elements(mut elements: Vec<Element>, format: TreeFormat) -> Entry {
let cmp = crate::namecmp::get_namecmp_func(format);
elements.sort_unstable_by(|a, b| cmp(&a.component, a.flag, &b.component, b.flag));
let mut underlying = BytesMut::new();
match format {
TreeFormat::Hg => {
@ -275,8 +277,7 @@ impl<'a> Elements<'a> {
};
while slice.len() >= name.len() {
match slice[..name.len()].cmp(name.as_slice()) {
// XXX: Some tests do not provide sorted entries.
Ordering::Less | Ordering::Greater => {
Ordering::Less => {
// Check the next entry.
match slice.iter().skip(HgId::hex_len()).position(|&x| x == b'\n') {
Some(position) => {
@ -297,6 +298,7 @@ impl<'a> Elements<'a> {
let flag = parse_hg_flag(slice.get(hex_end))?;
return Ok(Some((hgid, flag)));
}
Ordering::Greater => break,
}
}
Ok(None)