Skip to content

Commit 37da7cd

Browse files
committed
fix!: assure fifo or non-files aren't considered files, but are pruned instead.
That way, algorithms relying on dirwalking can still see them if they want to, but would have a hard time to use them (accidentally). Note that this replaces the `From` implementation with `entry::Kind::try_from_file_type()`, which makes this a breaking change.`
1 parent dc18d4b commit 37da7cd

File tree

4 files changed

+25
-12
lines changed

4 files changed

+25
-12
lines changed

gix-dir/src/entry.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,20 @@ impl Entry {
147147
}
148148
}
149149

150-
impl From<std::fs::FileType> for Kind {
151-
fn from(value: std::fs::FileType) -> Self {
152-
if value.is_dir() {
150+
impl Kind {
151+
/// Try to represent the file type `t` as `Entry`, or return `None` if it cannot be represented.
152+
///
153+
/// The latter can happen if it's a `pipe` for instance.
154+
pub fn try_from_file_type(t: std::fs::FileType) -> Option<Self> {
155+
Some(if t.is_dir() {
153156
Kind::Directory
154-
} else if value.is_symlink() {
157+
} else if t.is_symlink() {
155158
Kind::Symlink
156-
} else {
159+
} else if t.is_file() {
157160
Kind::File
158-
}
161+
} else {
162+
return None;
163+
})
159164
}
160165
}
161166

gix-dir/src/walk/classify.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ pub fn root(
2020
let mut last_length = None;
2121
let mut path_buf = worktree_root.to_owned();
2222
// These initial values kick in if worktree_relative_root.is_empty();
23-
let file_kind = path_buf.symlink_metadata().map(|m| m.file_type().into()).ok();
23+
let file_kind = path_buf
24+
.symlink_metadata()
25+
.ok()
26+
.and_then(|m| entry::Kind::try_from_file_type(m.file_type()));
2427
let mut out = path(&mut path_buf, buf, 0, file_kind, || None, options, ctx)?;
2528
let worktree_root_is_repository = out
2629
.disk_kind
@@ -32,7 +35,10 @@ pub fn root(
3235
}
3336
path_buf.push(component);
3437
buf.extend_from_slice(gix_path::os_str_into_bstr(component.as_os_str()).expect("no illformed UTF8"));
35-
let file_kind = path_buf.symlink_metadata().map(|m| m.file_type().into()).ok();
38+
let file_kind = path_buf
39+
.symlink_metadata()
40+
.ok()
41+
.and_then(|m| entry::Kind::try_from_file_type(m.file_type()));
3642

3743
out = path(
3844
&mut path_buf,
@@ -122,6 +128,8 @@ impl<'a> EntryRef<'a> {
122128
///
123129
/// Returns `(status, file_kind, pathspec_matches_how)` to identify the `status` on disk, along with a classification `file_kind`,
124130
/// and if `file_kind` is not a directory, the way the pathspec matched with `pathspec_matches_how`.
131+
///
132+
/// Note that non-files are pruned by default.
125133
pub fn path(
126134
path: &mut PathBuf,
127135
rela_path: &mut BString,

gix-dir/src/walk/readdir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub(super) fn recursive(
6464
current_bstr,
6565
if prev_len == 0 { 0 } else { prev_len + 1 },
6666
None,
67-
|| entry.file_type().ok().map(Into::into),
67+
|| entry.file_type().ok().and_then(entry::Kind::try_from_file_type),
6868
opts,
6969
ctx,
7070
)?;

gix-dir/tests/dir/walk.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ fn fifo_in_traversal() {
9797
assert_eq!(
9898
entries,
9999
&[
100+
entry_nokind(".git", Pruned).with_property(DotGit).with_match(Always),
100101
entry("dir-with-file/nested-file", Untracked, File),
101-
entry_nokind("dir/nested", Pruned),
102102
entry("file", Untracked, File),
103-
entry_nokind("top", Untracked),
104103
],
105-
"Non-files are simply pruned, and don't have a disk kind"
104+
"Non-files are not even pruned, they are ignored entirely.\
105+
If one day this isn't what we want, we can create an own filetype for them"
106106
);
107107
}
108108

0 commit comments

Comments
 (0)