mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 15:27:13 +03:00
status: use WorkingCopy status instead of static status
Summary: Now that we share a working copy between Rust and Python, we can just call status on it, instead of building a working copy in the static status invocation. Also moved last_write to become a parameter to status. Since we no longer create a WorkingCopy explicitly for the status, we don't have the opportunity to set it at that time. It probably didn't make sense to set it at working copy creation time anyway. Reviewed By: jordanwebster Differential Revision: D39753347 fbshipit-source-id: c03777c084d3eea5b9d6f0b0cb59126c19f06588
This commit is contained in:
parent
6b0448a753
commit
a2842e2d85
@ -953,29 +953,10 @@ class dirstate(object):
|
||||
def _ruststatus(
|
||||
self, match: "Callable[[str], bool]", ignored: bool, clean: bool, unknown: bool
|
||||
) -> "scmutil.status":
|
||||
if util.safehasattr(self._fs, "_fsmonitorstate"):
|
||||
filesystem = "watchman"
|
||||
elif "eden" in self._repo.requirements:
|
||||
filesystem = "eden"
|
||||
else:
|
||||
filesystem = "normal"
|
||||
|
||||
if ignored or clean:
|
||||
raise self.FallbackToPythonStatus
|
||||
|
||||
tree = self._repo._rsrepo.workingcopy().treestate()
|
||||
|
||||
return bindings.workingcopy.status.status(
|
||||
self._root,
|
||||
self._repo[self.p1()].manifest(),
|
||||
self._repo.fileslog.filescmstore,
|
||||
tree,
|
||||
self._lastnormaltime,
|
||||
match,
|
||||
unknown,
|
||||
filesystem,
|
||||
self._ui._uiconfig._rcfg,
|
||||
)
|
||||
return self._repo._rsrepo.workingcopy().status(match, self._lastnormaltime)
|
||||
|
||||
@perftrace.tracefunc("Status")
|
||||
def status(
|
||||
|
@ -18,28 +18,22 @@ use anyhow::anyhow;
|
||||
use anyhow::Error;
|
||||
use anyhow::Result;
|
||||
use cpython::*;
|
||||
use cpython_ext::convert::ImplInto;
|
||||
use cpython_ext::error::ResultPyErrExt;
|
||||
use cpython_ext::PyPathBuf;
|
||||
use parking_lot::RwLock;
|
||||
use pathmatcher::Matcher;
|
||||
use pyconfigparser::config as PyConfig;
|
||||
use pymanifest::treemanifest;
|
||||
use pypathmatcher::extract_matcher;
|
||||
use pypathmatcher::extract_option_matcher;
|
||||
use pytreestate::treestate;
|
||||
use rsworkingcopy::walker::WalkError;
|
||||
use rsworkingcopy::walker::Walker;
|
||||
use rsworkingcopy::workingcopy::WorkingCopy;
|
||||
use storemodel::ReadFileContents;
|
||||
|
||||
type ArcReadFileContents = Arc<dyn ReadFileContents<Error = anyhow::Error> + Send + Sync>;
|
||||
|
||||
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
|
||||
let name = [package, "workingcopy"].join(".");
|
||||
let m = PyModule::new(py, &name)?;
|
||||
m.add_class::<walker>(py)?;
|
||||
m.add_class::<status>(py)?;
|
||||
m.add_class::<workingcopy>(py)?;
|
||||
Ok(m)
|
||||
}
|
||||
|
||||
@ -88,63 +82,27 @@ py_class!(class walker |py| {
|
||||
|
||||
});
|
||||
|
||||
py_class!(class status |py| {
|
||||
@staticmethod
|
||||
def status(
|
||||
pyroot: PyPathBuf,
|
||||
pymanifest: treemanifest,
|
||||
pystore: ImplInto<ArcReadFileContents>,
|
||||
pytreestate: treestate,
|
||||
last_write: u32,
|
||||
pymatcher: Option<PyObject>,
|
||||
listunknown: bool,
|
||||
filesystem: &str,
|
||||
config: PyConfig,
|
||||
) -> PyResult<PyObject> {
|
||||
let root = pyroot.to_path_buf();
|
||||
let manifest = pymanifest.get_underlying(py);
|
||||
let store = pystore.into();
|
||||
let last_write = SystemTime::UNIX_EPOCH.checked_add(
|
||||
Duration::from_secs(last_write.into())).ok_or_else(|| anyhow!("Failed to convert {} to SystemTime", last_write)
|
||||
).map_pyerr(py)?;
|
||||
let matcher = extract_option_matcher(py, pymatcher)?;
|
||||
let filesystem = match filesystem {
|
||||
"normal" => {
|
||||
rsworkingcopy::filesystem::FileSystemType::Normal
|
||||
},
|
||||
"watchman" => {
|
||||
rsworkingcopy::filesystem::FileSystemType::Watchman
|
||||
},
|
||||
"eden" => {
|
||||
rsworkingcopy::filesystem::FileSystemType::Eden
|
||||
},
|
||||
_ => return Err(anyhow!("Unsupported filesystem type: {}", filesystem)).map_pyerr(py),
|
||||
};
|
||||
|
||||
let treestate = pytreestate.get_state(py);
|
||||
|
||||
let config = config.get_cfg(py);
|
||||
let status = py.allow_threads(|| rsworkingcopy::status::status(
|
||||
root,
|
||||
filesystem,
|
||||
manifest,
|
||||
store,
|
||||
treestate,
|
||||
last_write,
|
||||
matcher,
|
||||
listunknown,
|
||||
&config,
|
||||
));
|
||||
|
||||
let status = status.map_pyerr(py)?;
|
||||
pystatus::to_python_status(py, &status)
|
||||
}
|
||||
});
|
||||
|
||||
py_class!(pub class workingcopy |py| {
|
||||
data inner_wc: Arc<RwLock<WorkingCopy>>;
|
||||
data inner: Arc<RwLock<WorkingCopy>>;
|
||||
|
||||
def treestate(&self) -> PyResult<treestate> {
|
||||
treestate::create_instance(py, self.inner_wc(py).read().treestate())
|
||||
treestate::create_instance(py, self.inner(py).read().treestate())
|
||||
}
|
||||
|
||||
def status(
|
||||
&self,
|
||||
pymatcher: Option<PyObject>,
|
||||
lastwrite: u32,
|
||||
) -> PyResult<PyObject> {
|
||||
let wc = self.inner(py).write();
|
||||
let matcher = extract_option_matcher(py, pymatcher)?;
|
||||
let last_write = SystemTime::UNIX_EPOCH.checked_add(
|
||||
Duration::from_secs(lastwrite.into())).ok_or_else(|| anyhow!("Failed to convert {} to SystemTime", lastwrite)
|
||||
).map_pyerr(py)?;
|
||||
pystatus::to_python_status(py,
|
||||
&py.allow_threads(|| {
|
||||
wc.status(matcher, last_write)
|
||||
}).map_pyerr(py)?
|
||||
)
|
||||
}
|
||||
});
|
||||
|
@ -8,6 +8,7 @@
|
||||
mod print;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anyhow::Result;
|
||||
use clidispatch::errors;
|
||||
@ -163,7 +164,7 @@ pub fn run(ctx: ReqCtx<StatusOpts>, repo: &mut Repo, wc: &mut WorkingCopy) -> Re
|
||||
let (status, copymap) = match repo.config().get_or_default("status", "use-rust")? {
|
||||
true => {
|
||||
let matcher = Arc::new(AlwaysMatcher::new());
|
||||
let status = wc.status(matcher)?;
|
||||
let status = wc.status(matcher, SystemTime::UNIX_EPOCH)?;
|
||||
let copymap = wc.copymap()?.into_iter().collect();
|
||||
(status, copymap)
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Result;
|
||||
@ -418,7 +417,6 @@ impl Repo {
|
||||
treestate,
|
||||
tree_resolver,
|
||||
file_store,
|
||||
SystemTime::UNIX_EPOCH,
|
||||
&self.config,
|
||||
)?)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Result;
|
||||
@ -32,6 +33,7 @@ impl PendingChanges for EdenFileSystem {
|
||||
fn pending_changes(
|
||||
&self,
|
||||
_matcher: Arc<dyn Matcher + Send + Sync + 'static>,
|
||||
_last_write: SystemTime,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<PendingChangeResult>>>> {
|
||||
let result = edenfs_client::status::get_status(&self.root)?;
|
||||
Ok(Box::new(result.status.entries.into_iter().filter_map(
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anyhow::Result;
|
||||
use pathmatcher::Matcher;
|
||||
@ -37,5 +38,6 @@ pub trait PendingChanges {
|
||||
fn pending_changes(
|
||||
&self,
|
||||
matcher: Arc<dyn Matcher + Send + Sync + 'static>,
|
||||
last_write: SystemTime,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<PendingChangeResult>>>>;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anyhow::Result;
|
||||
use manifest_tree::ReadTreeManifest;
|
||||
@ -23,7 +24,6 @@ use vfs::VFS;
|
||||
use crate::filechangedetector::FileChangeDetector;
|
||||
use crate::filechangedetector::FileChangeDetectorTrait;
|
||||
use crate::filechangedetector::FileChangeResult;
|
||||
use crate::filechangedetector::HgModifiedTime;
|
||||
use crate::filechangedetector::ResolvedFileChangeResult;
|
||||
use crate::filesystem::PendingChangeResult;
|
||||
use crate::filesystem::PendingChanges as PendingChangesTrait;
|
||||
@ -41,7 +41,6 @@ pub struct PhysicalFileSystem {
|
||||
store: ArcReadFileContents,
|
||||
treestate: Arc<Mutex<TreeState>>,
|
||||
include_directories: bool,
|
||||
last_write: HgModifiedTime,
|
||||
num_threads: u8,
|
||||
}
|
||||
|
||||
@ -52,7 +51,6 @@ impl PhysicalFileSystem {
|
||||
store: ArcReadFileContents,
|
||||
treestate: Arc<Mutex<TreeState>>,
|
||||
include_directories: bool,
|
||||
last_write: HgModifiedTime,
|
||||
num_threads: u8,
|
||||
) -> Result<Self> {
|
||||
Ok(PhysicalFileSystem {
|
||||
@ -61,7 +59,6 @@ impl PhysicalFileSystem {
|
||||
store,
|
||||
treestate,
|
||||
include_directories,
|
||||
last_write,
|
||||
num_threads,
|
||||
})
|
||||
}
|
||||
@ -71,6 +68,7 @@ impl PendingChangesTrait for PhysicalFileSystem {
|
||||
fn pending_changes(
|
||||
&self,
|
||||
matcher: Arc<dyn Matcher + Send + Sync + 'static>,
|
||||
last_write: SystemTime,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<PendingChangeResult>>>> {
|
||||
let root = self.vfs.root().to_path_buf();
|
||||
let ident = identity::must_sniff_dir(&root)?;
|
||||
@ -86,7 +84,7 @@ impl PendingChangesTrait for PhysicalFileSystem {
|
||||
let file_change_detector = FileChangeDetector::new(
|
||||
self.treestate.clone(),
|
||||
self.vfs.clone(),
|
||||
self.last_write.clone(),
|
||||
last_write.try_into()?,
|
||||
manifests[0].clone(),
|
||||
self.store.clone(),
|
||||
);
|
||||
|
@ -7,12 +7,9 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anyhow::Result;
|
||||
use configparser::config::ConfigSet;
|
||||
use manifest::Manifest;
|
||||
use manifest_tree::ReadTreeManifest;
|
||||
use manifest_tree::TreeManifest;
|
||||
@ -22,17 +19,12 @@ use pathmatcher::ExactMatcher;
|
||||
use pathmatcher::Matcher;
|
||||
use status::Status;
|
||||
use status::StatusBuilder;
|
||||
use storemodel::ReadFileContents;
|
||||
use treestate::filestate::StateFlags;
|
||||
use treestate::treestate::TreeState;
|
||||
use types::HgId;
|
||||
use types::RepoPathBuf;
|
||||
|
||||
use crate::filesystem::ChangeType;
|
||||
use crate::filesystem::FileSystemType;
|
||||
use crate::workingcopy::WorkingCopy;
|
||||
|
||||
type ArcReadFileContents = Arc<dyn ReadFileContents<Error = anyhow::Error> + Send + Sync>;
|
||||
|
||||
struct FakeTreeResolver {
|
||||
pub manifest: Arc<RwLock<TreeManifest>>,
|
||||
@ -44,31 +36,6 @@ impl ReadTreeManifest for FakeTreeResolver {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn status(
|
||||
root: PathBuf,
|
||||
file_system_type: FileSystemType,
|
||||
manifest: Arc<RwLock<TreeManifest>>,
|
||||
store: ArcReadFileContents,
|
||||
treestate: Arc<Mutex<TreeState>>,
|
||||
last_write: SystemTime,
|
||||
matcher: Arc<dyn Matcher + Send + Sync + 'static>,
|
||||
_list_unknown: bool,
|
||||
config: &ConfigSet,
|
||||
) -> Result<Status> {
|
||||
let manifest_resolver = Arc::new(FakeTreeResolver { manifest });
|
||||
let working_copy = WorkingCopy::new(
|
||||
root,
|
||||
file_system_type,
|
||||
treestate,
|
||||
manifest_resolver,
|
||||
store,
|
||||
last_write,
|
||||
config,
|
||||
)?;
|
||||
|
||||
working_copy.status(matcher)
|
||||
}
|
||||
|
||||
/// Compute the status of the working copy relative to the current commit.
|
||||
#[allow(unused_variables)]
|
||||
pub fn compute_status(
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anyhow::Result;
|
||||
use manifest_tree::ReadTreeManifest;
|
||||
@ -21,7 +22,6 @@ use super::state::WatchmanState;
|
||||
use super::treestate::WatchmanTreeState;
|
||||
use crate::filechangedetector::ArcReadFileContents;
|
||||
use crate::filechangedetector::FileChangeDetector;
|
||||
use crate::filechangedetector::HgModifiedTime;
|
||||
use crate::filesystem::PendingChangeResult;
|
||||
use crate::filesystem::PendingChanges;
|
||||
use crate::workingcopy::WorkingCopy;
|
||||
@ -33,7 +33,6 @@ pub struct WatchmanFileSystem {
|
||||
treestate: Arc<Mutex<TreeState>>,
|
||||
tree_resolver: ArcReadTreeManifest,
|
||||
store: ArcReadFileContents,
|
||||
last_write: HgModifiedTime,
|
||||
}
|
||||
|
||||
impl WatchmanFileSystem {
|
||||
@ -42,14 +41,12 @@ impl WatchmanFileSystem {
|
||||
treestate: Arc<Mutex<TreeState>>,
|
||||
tree_resolver: ArcReadTreeManifest,
|
||||
store: ArcReadFileContents,
|
||||
last_write: HgModifiedTime,
|
||||
) -> Result<Self> {
|
||||
Ok(WatchmanFileSystem {
|
||||
vfs: VFS::new(root)?,
|
||||
treestate,
|
||||
tree_resolver,
|
||||
store,
|
||||
last_write,
|
||||
})
|
||||
}
|
||||
|
||||
@ -84,6 +81,7 @@ impl PendingChanges for WatchmanFileSystem {
|
||||
fn pending_changes(
|
||||
&self,
|
||||
_matcher: Arc<dyn Matcher + Send + Sync + 'static>,
|
||||
last_write: SystemTime,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<PendingChangeResult>>>> {
|
||||
let state = WatchmanState::new(WatchmanTreeState {
|
||||
treestate: self.treestate.clone(),
|
||||
@ -97,7 +95,7 @@ impl PendingChanges for WatchmanFileSystem {
|
||||
let file_change_detector = FileChangeDetector::new(
|
||||
self.treestate.clone(),
|
||||
self.vfs.clone(),
|
||||
self.last_write.clone(),
|
||||
last_write.try_into()?,
|
||||
manifests[0].clone(),
|
||||
self.store.clone(),
|
||||
);
|
||||
|
@ -35,7 +35,6 @@ use types::RepoPathBuf;
|
||||
|
||||
#[cfg(feature = "eden")]
|
||||
use crate::edenfs::EdenFileSystem;
|
||||
use crate::filechangedetector::HgModifiedTime;
|
||||
use crate::filesystem::FileSystemType;
|
||||
use crate::filesystem::PendingChangeResult;
|
||||
use crate::filesystem::PendingChanges;
|
||||
@ -74,7 +73,6 @@ impl WorkingCopy {
|
||||
treestate: Arc<Mutex<TreeState>>,
|
||||
tree_resolver: ArcReadTreeManifest,
|
||||
filestore: ArcReadFileContents,
|
||||
last_write: SystemTime,
|
||||
config: &ConfigSet,
|
||||
) -> Result<Self> {
|
||||
tracing::debug!(target: "dirstate_size", dirstate_size=treestate.lock().len());
|
||||
@ -93,7 +91,6 @@ impl WorkingCopy {
|
||||
treestate.clone(),
|
||||
tree_resolver.clone(),
|
||||
filestore,
|
||||
last_write,
|
||||
)?);
|
||||
|
||||
Ok(WorkingCopy {
|
||||
@ -144,9 +141,7 @@ impl WorkingCopy {
|
||||
treestate: Arc<Mutex<TreeState>>,
|
||||
tree_resolver: ArcReadTreeManifest,
|
||||
store: ArcReadFileContents,
|
||||
last_write: SystemTime,
|
||||
) -> Result<FileSystem> {
|
||||
let last_write: HgModifiedTime = last_write.try_into()?;
|
||||
let inner: Box<dyn PendingChanges + Send> = match file_system_type {
|
||||
FileSystemType::Normal => Box::new(PhysicalFileSystem::new(
|
||||
root.clone(),
|
||||
@ -154,7 +149,6 @@ impl WorkingCopy {
|
||||
store.clone(),
|
||||
treestate.clone(),
|
||||
false,
|
||||
last_write,
|
||||
8,
|
||||
)?),
|
||||
FileSystemType::Watchman => Box::new(WatchmanFileSystem::new(
|
||||
@ -162,7 +156,6 @@ impl WorkingCopy {
|
||||
treestate.clone(),
|
||||
tree_resolver,
|
||||
store.clone(),
|
||||
last_write,
|
||||
)?),
|
||||
FileSystemType::Eden => {
|
||||
#[cfg(not(feature = "eden"))]
|
||||
@ -238,7 +231,11 @@ impl WorkingCopy {
|
||||
Ok(Arc::new(UnionMatcher::new(sparse_matchers)))
|
||||
}
|
||||
|
||||
pub fn status(&self, matcher: Arc<dyn Matcher + Send + Sync + 'static>) -> Result<Status> {
|
||||
pub fn status(
|
||||
&self,
|
||||
matcher: Arc<dyn Matcher + Send + Sync + 'static>,
|
||||
last_write: SystemTime,
|
||||
) -> Result<Status> {
|
||||
let added_files = self.added_files()?;
|
||||
|
||||
let manifests =
|
||||
@ -269,7 +266,7 @@ impl WorkingCopy {
|
||||
.filesystem
|
||||
.lock()
|
||||
.inner
|
||||
.pending_changes(matcher.clone())?
|
||||
.pending_changes(matcher.clone(), last_write)?
|
||||
.filter_map(|result| match result {
|
||||
Ok(PendingChangeResult::File(change_type)) => {
|
||||
match matcher.matches_file(change_type.get_path()) {
|
||||
|
Loading…
Reference in New Issue
Block a user