fsmonitor: exclude .git and .jj directories from changed files

This ensures that the root fsmonitor_matcher matches nothing if there are no
working-copy changes. The query result can be observed by "jj debug watchman
query-changed-files".

I don't have expertise on watchman query language, but using the watchman API
is probably better than .filter()-ing the result manually.
This commit is contained in:
Yuya Nishihara 2023-11-16 13:01:08 +09:00
parent ea22f90018
commit 74c4ef32aa

View file

@ -63,6 +63,7 @@ pub mod watchman {
use itertools::Itertools;
use thiserror::Error;
use tracing::{info, instrument};
use watchman_client::expr;
use watchman_client::prelude::{
Clock as InnerClock, ClockSpec, NameOnly, QueryRequestCommon, QueryResult,
};
@ -172,6 +173,26 @@ pub mod watchman {
&self,
previous_clock: Option<Clock>,
) -> Result<(Clock, Option<Vec<PathBuf>>), Error> {
// TODO: might be better to specify query options by caller, but we
// shouldn't expose the underlying watchman API too much.
let exclude_dirs = [Path::new(".git"), Path::new(".jj")];
let excludes = itertools::chain(
// the directories themselves
[expr::Expr::Name(expr::NameTerm {
paths: exclude_dirs.iter().map(|&name| name.to_owned()).collect(),
wholename: true,
})],
// and all files under the directories
exclude_dirs.iter().map(|&name| {
expr::Expr::DirName(expr::DirNameTerm {
path: name.to_owned(),
depth: None,
})
}),
)
.collect();
let expression = expr::Expr::Not(Box::new(expr::Expr::Any(excludes)));
info!("Querying Watchman for changed files...");
let QueryResult {
version: _,
@ -189,6 +210,7 @@ pub mod watchman {
&self.resolved_root,
QueryRequestCommon {
since: previous_clock.map(|Clock(clock)| clock),
expression: Some(expression),
..Default::default()
},
)