##// END OF EJS Templates
copies: stop attempt to avoid extra dict copies around branching...
copies: stop attempt to avoid extra dict copies around branching In the python code, we attempt to avoid unnecessary dict copies when gathering copy information. However that logic is wobbly and I keep running into case where independent branches affects each others. With the current code we can't ensure we are the only "user" of dict when dealing with merge. This caused havoc in the next series on tests I am about to introduce. So for now I am disabling the faulty optimisation. I believe we will need a dedicated overlay to deal with the "copy on write logic" to have something correct. I am also hoping to find time to build dedicated test case for this category of problem instead of relying on side effect in other tests. However for now I am focussing on another issue. Differential Revision: https://phab.mercurial-scm.org/D9608

File last commit:

r46669:fd47483f default
r46800:cb8b2ee8 default
Show More
dirstate_status.rs
133 lines | 5.1 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
hg-core: define a `dirstate_status` `Operation`...
r45673 // dirstate_status.rs
//
// 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.
use crate::dirstate::status::{build_response, Dispatch, HgPathCow, Status};
use crate::matchers::Matcher;
use crate::{DirstateStatus, StatusError};
/// A tuple of the paths that need to be checked in the filelog because it's
/// ambiguous whether they've changed, and the rest of the already dispatched
/// files.
pub type LookupAndStatus<'a> = (Vec<HgPathCow<'a>>, DirstateStatus<'a>);
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 #[cfg(feature = "dirstate-tree")]
impl<'a, M: Matcher + Sync> Status<'a, M> {
pub(crate) fn run(&self) -> Result<LookupAndStatus<'a>, StatusError> {
let (traversed_sender, traversed_receiver) =
Simon Sapin
rust: use crossbeam-channel crate directly...
r46669 crossbeam_channel::unbounded();
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185
// Step 1: check the files explicitly mentioned by the user
let (work, mut results) = self.walk_explicit(traversed_sender.clone());
// Step 2: Check files in the dirstate
if !self.matcher.is_exact() {
self.extend_from_dmap(&mut results);
}
// Step 3: Check the working directory if listing unknowns
if !work.is_empty() {
// Hashmaps are quite a bit slower to build than vecs, so only
// build it if needed.
let mut old_results = None;
// Step 2: recursively check the working directory for changes if
// needed
for (dir, dispatch) in work {
match dispatch {
Dispatch::Directory { was_file } => {
if was_file {
results.push((dir.to_owned(), Dispatch::Removed));
}
if self.options.list_ignored
|| self.options.list_unknown
&& !self.dir_ignore(&dir)
{
if old_results.is_none() {
old_results =
Some(results.iter().cloned().collect());
}
self.traverse(
&dir,
old_results
.as_ref()
.expect("old results should exist"),
&mut results,
traversed_sender.clone(),
Raphaël Gomès
rust-status: don't bubble up os errors, translate them to bad matches...
r46466 );
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 }
}
_ => {
unreachable!("There can only be directories in `work`")
}
}
}
}
drop(traversed_sender);
let traversed = traversed_receiver.into_iter().collect();
Ok(build_response(results, traversed))
}
}
#[cfg(not(feature = "dirstate-tree"))]
Antoine Cezar
hg-core: remove the `Operation` trait...
r45917 impl<'a, M: Matcher + Sync> Status<'a, M> {
pub(crate) fn run(&self) -> Result<LookupAndStatus<'a>, StatusError> {
Raphaël Gomès
hg-core: define a `dirstate_status` `Operation`...
r45673 let (traversed_sender, traversed_receiver) =
Simon Sapin
rust: use crossbeam-channel crate directly...
r46669 crossbeam_channel::unbounded();
Raphaël Gomès
hg-core: define a `dirstate_status` `Operation`...
r45673
// Step 1: check the files explicitly mentioned by the user
let (work, mut results) = self.walk_explicit(traversed_sender.clone());
if !work.is_empty() {
// Hashmaps are quite a bit slower to build than vecs, so only
// build it if needed.
let old_results = results.iter().cloned().collect();
// Step 2: recursively check the working directory for changes if
// needed
for (dir, dispatch) in work {
match dispatch {
Dispatch::Directory { was_file } => {
if was_file {
results.push((dir.to_owned(), Dispatch::Removed));
}
if self.options.list_ignored
|| self.options.list_unknown
&& !self.dir_ignore(&dir)
{
self.traverse(
&dir,
&old_results,
&mut results,
traversed_sender.clone(),
Raphaël Gomès
rust-status: don't bubble up os errors, translate them to bad matches...
r46466 );
Raphaël Gomès
hg-core: define a `dirstate_status` `Operation`...
r45673 }
}
_ => {
unreachable!("There can only be directories in `work`")
}
}
}
}
if !self.matcher.is_exact() {
if self.options.list_unknown {
Raphaël Gomès
rust-status: don't bubble up os errors, translate them to bad matches...
r46466 self.handle_unknowns(&mut results);
Raphaël Gomès
hg-core: define a `dirstate_status` `Operation`...
r45673 } else {
// TODO this is incorrect, see issue6335
// This requires a fix in both Python and Rust that can happen
// with other pending changes to `status`.
self.extend_from_dmap(&mut results);
}
}
drop(traversed_sender);
let traversed = traversed_receiver.into_iter().collect();
Ok(build_response(results, traversed))
}
}