Skip to content

Commit 9a26351

Browse files
Muir Mandersfacebook-github-bot
authored andcommitted
status: hack up various things to not assume ".hg" dot dir
Summary: Update watchman queries, Python walker, and Rust walker to use the repo's identity's dot dir instead of hard coding ".hg". I was able to pass the dot dir around in most places, but I resorted to re-sniffing the identity in the PhysicalFileSystem. Reviewed By: DurhamG Differential Revision: D39105266 fbshipit-source-id: a58f75889c4b1d4ea3b2e04817224c26b21a33ea
1 parent e448831 commit 9a26351

File tree

7 files changed

+84
-23
lines changed

7 files changed

+84
-23
lines changed

eden/scm/edenscm/ext/fsmonitor/__init__.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,14 @@ def _finddirs(ui, fs):
313313
"expression": [
314314
"allof",
315315
["type", "d"],
316-
["not", ["anyof", ["dirname", ".hg"], ["name", ".hg", "wholename"]]],
316+
[
317+
"not",
318+
[
319+
"anyof",
320+
["dirname", ui.identity.dotdir()],
321+
["name", ui.identity.dotdir(), "wholename"],
322+
],
323+
],
317324
],
318325
"sync_timeout": int(state.timeout * 1000),
319326
"empty_on_fresh_instance": state.walk_on_invalidate,
@@ -477,7 +484,11 @@ def dirfilter(path):
477484
# Use the user-configured timeout for the query.
478485
# Add a little slack over the top of the user query to allow for
479486
# overheads while transferring the data
480-
excludes = ["anyof", ["dirname", ".hg"], ["name", ".hg", "wholename"]]
487+
excludes = [
488+
"anyof",
489+
["dirname", self._ui.identity.dotdir()],
490+
["name", self._ui.identity.dotdir(), "wholename"],
491+
]
481492
# Exclude submodules.
482493
if git.isgitformat(self._repo):
483494
submods = git.parsesubmodules(self._repo[None])
@@ -723,7 +734,7 @@ def nf():
723734
state.setdroplist(droplist)
724735
state.setignorelist(ignorelist)
725736

726-
results.pop(".hg", None)
737+
results.pop(self.ui.identity.dotdir(), None)
727738
return pycompat.iteritems(results)
728739

729740

@@ -979,7 +990,7 @@ def _detectrace(self, match=None):
979990
"expression": [
980991
"allof",
981992
["type", "f"],
982-
["not", ["anyof", ["dirname", ".hg"]]],
993+
["not", ["anyof", ["dirname", ui.identity.dotdir()]]],
983994
],
984995
"sync_timeout": int(state.timeout * 1000),
985996
"empty_on_fresh_instance": True,

eden/scm/edenscm/ext/fsmonitor/state.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,11 @@ def set(self, clock, ignorehash, notefiles):
156156

157157
def invalidate(self, reason=None):
158158
try:
159-
os.unlink(os.path.join(self._rootdir, ".hg", "fsmonitor.state"))
159+
os.unlink(
160+
os.path.join(
161+
self._rootdir, self._ui.identity.dotdir(), "fsmonitor.state"
162+
)
163+
)
160164
except OSError as inst:
161165
if inst.errno != errno.ENOENT:
162166
raise

eden/scm/edenscm/filesystem.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,9 @@ def bad(self, path, msg):
268268

269269
traversedir = bool(match.traversedir)
270270
threadcount = self.ui.configint("workingcopy", "rustwalkerthreads")
271-
walker = workingcopy.walker(join(""), match, traversedir, threadcount)
271+
walker = workingcopy.walker(
272+
join(""), self.ui.identity.dotdir(), match, traversedir, threadcount
273+
)
272274
for fn in walker:
273275
fn = self.dirstate.normalize(fn)
274276
st = util.lstat(join(fn))
@@ -367,16 +369,18 @@ def _walk(self, match, listignored=False):
367369
explicitfiles = set(match.files())
368370
explicitdirs = set(util.dirs(explicitfiles))
369371

372+
dotdir = self.ui.identity.dotdir()
373+
370374
work = [""]
371375
wadd = work.append
372376
seen = set()
373377
while work:
374378
nd = work.pop()
375-
if not match.visitdir(nd) or nd == ".hg":
379+
if not match.visitdir(nd) or nd == dotdir:
376380
continue
377381
skip = None
378382
if nd != "":
379-
skip = ".hg"
383+
skip = dotdir
380384
try:
381385
entries = listdir(join(nd), stat=True, skip=skip)
382386
except OSError as inst:

eden/scm/edenscmnative/bindings/modules/pyworkingcopy/src/lib.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,22 @@ pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
3939
py_class!(class walker |py| {
4040
data inner: RefCell<Walker<Arc<dyn Matcher + Sync + Send>>>;
4141
data _errors: RefCell<Vec<Error>>;
42-
def __new__(_cls, root: PyPathBuf, pymatcher: PyObject, include_directories: bool, thread_count: u8) -> PyResult<walker> {
42+
def __new__(
43+
_cls,
44+
root: PyPathBuf,
45+
dot_dir: String,
46+
pymatcher: PyObject,
47+
include_directories: bool,
48+
thread_count: u8,
49+
) -> PyResult<walker> {
4350
let matcher = extract_matcher(py, pymatcher)?;
44-
let walker = Walker::new(root.to_path_buf(), matcher, include_directories, thread_count).map_pyerr(py)?;
51+
let walker = Walker::new(
52+
root.to_path_buf(),
53+
dot_dir,
54+
matcher,
55+
include_directories,
56+
thread_count,
57+
).map_pyerr(py)?;
4558
walker::create_instance(py, RefCell::new(walker), RefCell::new(Vec::new()))
4659
}
4760

eden/scm/lib/workingcopy/src/physicalfs.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,11 @@ impl PendingChangesTrait for PhysicalFileSystem {
7171
&self,
7272
matcher: Arc<dyn Matcher + Send + Sync + 'static>,
7373
) -> Result<Box<dyn Iterator<Item = Result<PendingChangeResult>>>> {
74+
let root = self.vfs.root().to_path_buf();
75+
let ident = identity::must_sniff_dir(&root)?;
7476
let walker = Walker::new(
75-
self.vfs.root().to_path_buf(),
77+
root,
78+
ident.dot_dir().to_string(),
7679
matcher.clone(),
7780
false,
7881
self.num_threads,

eden/scm/lib/workingcopy/src/walker.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,18 +105,25 @@ where
105105
/// multi-threaded walker will be created.
106106
pub fn new(
107107
root: PathBuf,
108+
dot_dir: String,
108109
matcher: M,
109110
include_directories: bool,
110111
num_threads: u8,
111112
) -> Result<Self> {
112113
let inner = match NonZeroU8::new(num_threads) {
113114
Some(num_threads) => WalkerType::Multi(MultiWalker::new(
114115
root,
116+
dot_dir,
115117
matcher,
116118
include_directories,
117119
num_threads,
118120
)?),
119-
None => WalkerType::Single(SingleWalker::new(root, matcher, include_directories)?),
121+
None => WalkerType::Single(SingleWalker::new(
122+
root,
123+
dot_dir,
124+
matcher,
125+
include_directories,
126+
)?),
120127
};
121128
Ok(Walker(inner))
122129
}
@@ -148,13 +155,19 @@ struct SingleWalker<M> {
148155
results: Vec<Result<WalkEntry>>,
149156
matcher: M,
150157
include_directories: bool,
158+
dot_dir: String,
151159
}
152160

153161
impl<M> SingleWalker<M>
154162
where
155163
M: Matcher,
156164
{
157-
pub fn new(root: PathBuf, matcher: M, include_directories: bool) -> Result<Self> {
165+
pub fn new(
166+
root: PathBuf,
167+
dot_dir: String,
168+
matcher: M,
169+
include_directories: bool,
170+
) -> Result<Self> {
158171
let mut dir_matches = vec![];
159172
if matcher.matches_directory(&RepoPathBuf::new())? != DirectoryMatch::Nothing {
160173
dir_matches.push(RepoPathBuf::new());
@@ -165,6 +178,7 @@ where
165178
results: Vec::new(),
166179
matcher,
167180
include_directories,
181+
dot_dir,
168182
};
169183
Ok(walker)
170184
}
@@ -190,7 +204,7 @@ where
190204
.push(Ok(WalkEntry::File(candidate_path, entry.metadata()?)));
191205
}
192206
} else if filetype.is_dir() {
193-
if filename.as_str() != ".hg"
207+
if filename.as_str() != self.dot_dir
194208
&& self
195209
.matcher
196210
.matches_directory(candidate_path.as_repo_path())?
@@ -214,7 +228,7 @@ where
214228
}
215229
let abs_next_dir = self.root.join(next_dir.as_str());
216230
// Don't process the directory if it contains a .hg directory, unless it's the root.
217-
if next_dir.is_empty() || !Path::exists(&abs_next_dir.join(".hg")) {
231+
if next_dir.is_empty() || !Path::exists(&abs_next_dir.join(&self.dot_dir)) {
218232
for entry in fs::read_dir(abs_next_dir)
219233
.map_err(|e| WalkError::IOError(next_dir.clone(), e))?
220234
{
@@ -271,6 +285,7 @@ struct MultiWalker<M> {
271285
result_receiver: Receiver<Result<WalkEntry>>,
272286
has_walked: bool,
273287
payload: Arc<WalkerData<M>>,
288+
dot_dir: String,
274289
}
275290

276291
impl<M> MultiWalker<M>
@@ -285,6 +300,7 @@ where
285300

286301
pub fn new(
287302
root: PathBuf,
303+
dot_dir: String,
288304
matcher: M,
289305
include_directories: bool,
290306
num_threads: NonZeroU8,
@@ -308,13 +324,15 @@ where
308324
matcher,
309325
include_directories,
310326
}),
327+
dot_dir,
311328
})
312329
}
313330

314331
// WARNING: SIDE EFFECTS - if entry matches and is child directory, will push
315332
// child and increment busy_nodes atomic.
316333
fn match_entry_and_enqueue(
317334
dir: &RepoPathBuf,
335+
dot_dir: &str,
318336
entry: DirEntry,
319337
shared_data: Arc<WalkerData<M>>,
320338
) -> Result<()> {
@@ -339,7 +357,7 @@ where
339357
.enqueue_result(Ok(WalkEntry::File(candidate_path, entry.metadata()?)))?;
340358
}
341359
} else if filetype.is_dir() {
342-
if filename.as_str() != ".hg"
360+
if filename.as_str() != dot_dir
343361
&& shared_data
344362
.matcher
345363
.matches_directory(candidate_path.as_repo_path())?
@@ -368,6 +386,7 @@ where
368386

369387
for _t in 0..self.threads.capacity() {
370388
let shared_data = self.payload.clone();
389+
let dot_dir = self.dot_dir.clone();
371390

372391
// TODO make sure that _t is different for each thread
373392
self.threads.push(thread::spawn(move || {
@@ -392,6 +411,7 @@ where
392411
entry.map_err(|e| WalkError::IOError(dir.clone(), e))?;
393412
if let Err(e) = MultiWalker::match_entry_and_enqueue(
394413
&dir,
414+
&dot_dir,
395415
entry,
396416
shared_data.clone(),
397417
) {
@@ -496,7 +516,7 @@ mod tests {
496516
let files = vec!["dirA/a.txt", "b.txt"];
497517
let root_dir = create_directory(&directories, &files)?;
498518
let root_path = PathBuf::from(root_dir.path());
499-
let walker = SingleWalker::new(root_path, NeverMatcher::new(), false)?;
519+
let walker = SingleWalker::new(root_path, ".hg".to_string(), NeverMatcher::new(), false)?;
500520
let walked_files: Result<Vec<_>> = walker.collect();
501521
let walked_files = walked_files?;
502522
assert!(walked_files.is_empty());
@@ -509,7 +529,7 @@ mod tests {
509529
let files = vec!["dirA/a.txt", "dirA/b.txt", "dirB/dirC/dirD/c.txt"];
510530
let root_dir = create_directory(&directories, &files)?;
511531
let root_path = PathBuf::from(root_dir.path());
512-
let walker = SingleWalker::new(root_path, AlwaysMatcher::new(), false)?;
532+
let walker = SingleWalker::new(root_path, ".hg".to_string(), AlwaysMatcher::new(), false)?;
513533
let walked_files: Result<Vec<_>> = walker.collect();
514534
let walked_files = walked_files?;
515535
assert_eq!(walked_files.len(), 3);
@@ -527,6 +547,7 @@ mod tests {
527547
let root_path = PathBuf::from(root_dir.path());
528548
let walker = SingleWalker::new(
529549
root_path,
550+
".hg".to_string(),
530551
TreeMatcher::from_rules(["foo/bar/**"].iter()).unwrap(),
531552
false,
532553
)?;
@@ -546,7 +567,7 @@ mod tests {
546567
let files = vec!["dirA/a.txt", "dirA/b.txt", "dirB/dirC/dirD/c.txt"];
547568
let root_dir = create_directory(&directories, &files)?;
548569
let root_path = PathBuf::from(root_dir.path());
549-
let walker = SingleWalker::new(root_path, AlwaysMatcher::new(), true)?;
570+
let walker = SingleWalker::new(root_path, ".hg".to_string(), AlwaysMatcher::new(), true)?;
550571
let walked_files: Result<Vec<_>> = walker.collect();
551572
let walked_files = walked_files?;
552573
// Includes root dir ""
@@ -575,6 +596,7 @@ mod tests {
575596
let root_path = PathBuf::from(root_dir.path());
576597
let walker = MultiWalker::new(
577598
root_path,
599+
".hg".to_string(),
578600
NeverMatcher::new(),
579601
false,
580602
NonZeroU8::new(5).unwrap(),
@@ -593,6 +615,7 @@ mod tests {
593615
let root_path = PathBuf::from(root_dir.path());
594616
let walker = MultiWalker::new(
595617
root_path,
618+
".hg".to_string(),
596619
AlwaysMatcher::new(),
597620
false,
598621
NonZeroU8::new(1).unwrap(),
@@ -614,6 +637,7 @@ mod tests {
614637
let root_path = PathBuf::from(root_dir.path());
615638
let walker = MultiWalker::new(
616639
root_path,
640+
".hg".to_string(),
617641
AlwaysMatcher::new(),
618642
false,
619643
NonZeroU8::new(2).unwrap(),
@@ -635,6 +659,7 @@ mod tests {
635659
let root_path = PathBuf::from(root_dir.path());
636660
let walker = MultiWalker::new(
637661
root_path,
662+
".hg".to_string(),
638663
AlwaysMatcher::new(),
639664
false,
640665
NonZeroU8::new(u8::MAX).unwrap(),
@@ -656,6 +681,7 @@ mod tests {
656681
let root_path = PathBuf::from(root_dir.path());
657682
let walker = MultiWalker::new(
658683
root_path,
684+
".hg".to_string(),
659685
TreeMatcher::from_rules(["foo/bar/**"].iter()).unwrap(),
660686
false,
661687
NonZeroU8::new(4).unwrap(),
@@ -678,6 +704,7 @@ mod tests {
678704
let root_path = PathBuf::from(root_dir.path());
679705
let walker = MultiWalker::new(
680706
root_path,
707+
".hg".to_string(),
681708
AlwaysMatcher::new(),
682709
true,
683710
NonZeroU8::new(2).unwrap(),

eden/scm/tests/test-identity.t

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ Clone can create a ".sl" repo.
5353
wlock.lock
5454

5555
$ cd cloned
56-
Status kind of runs, but doesn't ignore ".sl" properly (for non-watchman)
57-
$ LOG=configparser::hg=info hg status | head -1
58-
? .sl/.dir_lock (?)
56+
Status works in ".sl" repo
57+
$ LOG=configparser::hg=info hg status -A
5958
INFO configparser::hg: loading config repo_path=Some("$TESTTMP/clone_me/cloned")
60-
59+
C foo

0 commit comments

Comments
 (0)