Skip to content

Commit 11ac677

Browse files
committed
fix: status retrieval now deals with non-file entries by ignoring them when possible.
1 parent a7c4100 commit 11ac677

File tree

10 files changed

+92
-14
lines changed

10 files changed

+92
-14
lines changed

gix-status/src/index_as_worktree/types.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,12 @@ impl Outcome {
103103
pub enum Change<T = (), U = ()> {
104104
/// This corresponding file does not exist in the worktree anymore.
105105
Removed,
106-
/// The type of file changed compared to the worktree, i.e. a symlink s now a file.
106+
/// The type of file changed compared to the worktree, i.e. a symlink is now a file, or a file was replaced with a named pipe.
107+
///
108+
/// ### Deviation
109+
///
110+
/// A change to a non-file is marked as `modification` in Git, but that's related to the content which we can't evaluate.
111+
/// Hence, a type-change is considered more appropriate.
107112
Type,
108113
/// This worktree file was modified in some form, like a permission change or content change or both,
109114
/// as compared to this entry.

gix-status/src/index_as_worktree_with_renames/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,11 @@ pub(super) mod function {
387387

388388
impl<T, U> gix_dir::walk::Delegate for Delegate<'_, '_, T, U> {
389389
fn emit(&mut self, entry: EntryRef<'_>, collapsed_directory_status: Option<Status>) -> Action {
390-
let entry = entry.to_owned();
391-
self.tx.send(Event::DirEntry(entry, collapsed_directory_status)).ok();
390+
// Status never shows untracked non-files
391+
if entry.disk_kind != Some(gix_dir::entry::Kind::NonFile) {
392+
let entry = entry.to_owned();
393+
self.tx.send(Event::DirEntry(entry, collapsed_directory_status)).ok();
394+
}
392395

393396
if self.should_interrupt.load(Ordering::Relaxed) {
394397
Action::Cancel

gix-status/tests/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ publish = false
1212
rust-version = "1.65"
1313

1414
[[test]]
15-
name = "worktree"
16-
path = "worktree.rs"
15+
name = "status"
16+
path = "status/mod.rs"
1717

1818
[features]
1919
gix-features-parallel = ["gix-features/parallel"]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
status_unchanged.tar
22
status_changed.tar
33
symlink_stack.tar
4+
status_nonfile.tar
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
set -eu -o pipefail
3+
4+
git init -q untracked
5+
(cd untracked
6+
touch file && git add file && git commit -m "just to get an index for the test-suite"
7+
8+
mkfifo pipe
9+
git status
10+
)
11+
12+
git init -q tracked-swapped
13+
(cd tracked-swapped
14+
touch file && git add file && git commit -m "it starts out as trackable file"
15+
16+
rm file && mkfifo file
17+
git status
18+
)
19+

gix-status/tests/status/index_as_worktree.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ fn fixture(name: &str, expected_status: &[Expectation<'_>]) -> Outcome {
3737
fixture_filtered(name, &[], expected_status)
3838
}
3939

40+
fn nonfile_fixture(name: &str, expected_status: &[Expectation<'_>]) -> Outcome {
41+
fixture_filtered_detailed("status_nonfile", name, &[], expected_status, |_| {}, false)
42+
}
43+
4044
fn fixture_with_index(
4145
name: &str,
4246
prepare_index: impl FnMut(&mut gix_index::State),
@@ -185,6 +189,19 @@ fn status_removed() -> EntryStatus {
185189
Change::Removed.into()
186190
}
187191

192+
#[test]
193+
#[cfg(unix)]
194+
fn nonfile_untracked_are_not_visible() {
195+
// And generally, untracked aren't visible here.
196+
nonfile_fixture("untracked", &[]);
197+
}
198+
199+
#[test]
200+
#[cfg(unix)]
201+
fn tracked_changed_to_non_file() {
202+
nonfile_fixture("tracked-swapped", &[(BStr::new(b"file"), 0, Change::Type.into())]);
203+
}
204+
188205
#[test]
189206
fn removed() {
190207
let out = fixture(

gix-status/tests/status/index_as_worktree_with_renames.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::status::fixture_path;
1+
use crate::fixture_path;
22
use bstr::ByteSlice;
33
use gix_diff::blob::pipeline::WorktreeRoots;
44
use gix_diff::rewrites::CopySource;
@@ -83,6 +83,7 @@ fn changed_and_untracked_and_renamed() {
8383
track_empty: true,
8484
};
8585
let out = fixture_filtered_detailed(
86+
"status_many.sh",
8687
"changed-and-untracked-and-renamed",
8788
&[],
8889
&expectations_with_dirwalk,
@@ -100,9 +101,38 @@ fn changed_and_untracked_and_renamed() {
100101
);
101102
}
102103

104+
#[test]
105+
#[cfg(unix)]
106+
fn nonfile_untracked_are_not_visible() {
107+
fixture_filtered_detailed(
108+
"status_nonfile.sh",
109+
"untracked",
110+
&[],
111+
&[],
112+
None,
113+
Some(Default::default()),
114+
);
115+
}
116+
117+
#[test]
118+
#[cfg(unix)]
119+
fn tracked_changed_to_non_file() {
120+
fixture_filtered_detailed(
121+
"status_nonfile.sh",
122+
"tracked-swapped",
123+
&[],
124+
&[Expectation::Modification {
125+
rela_path: "file",
126+
status: Change::Type.into(),
127+
}],
128+
None,
129+
Some(Default::default()),
130+
);
131+
}
103132
#[test]
104133
fn changed_and_untracked() {
105134
let out = fixture_filtered_detailed(
135+
"status_many.sh",
106136
"changed-and-untracked",
107137
&[],
108138
&[Expectation::Modification {
@@ -144,6 +174,7 @@ fn changed_and_untracked() {
144174
},
145175
];
146176
let out = fixture_filtered_detailed(
177+
"status_many.sh",
147178
"changed-and-untracked",
148179
&[],
149180
&expectations_with_dirwalk,
@@ -163,6 +194,7 @@ fn changed_and_untracked() {
163194
assert_eq!(out.rewrites, None, "rewrites are still not configured");
164195

165196
let out = fixture_filtered_detailed(
197+
"status_many.sh",
166198
"changed-and-untracked",
167199
&[],
168200
&expectations_with_dirwalk,
@@ -179,6 +211,7 @@ fn changed_and_untracked() {
179211
}
180212

181213
fn fixture_filtered_detailed(
214+
script: &str,
182215
subdir: &str,
183216
pathspecs: &[&str],
184217
expected: &[Expectation<'_>],
@@ -193,11 +226,11 @@ fn fixture_filtered_detailed(
193226
out
194227
}
195228

196-
let worktree = fixture_path("status_many.sh").join(subdir);
229+
let worktree = fixture_path(script).join(subdir);
197230
let git_dir = worktree.join(".git");
198231
let index = gix_index::File::at(git_dir.join("index"), gix_hash::Kind::Sha1, false, Default::default()).unwrap();
199232
let search = gix_pathspec::Search::from_specs(
200-
crate::status::index_as_worktree::to_pathspecs(pathspecs),
233+
crate::index_as_worktree::to_pathspecs(pathspecs),
201234
None,
202235
std::path::Path::new(""),
203236
)
@@ -247,7 +280,7 @@ fn fixture_filtered_detailed(
247280
object_hash: gix_hash::Kind::Sha1,
248281
tracked_file_modifications: gix_status::index_as_worktree::Options {
249282
fs: capabilities,
250-
stat: crate::status::index_as_worktree::TEST_OPTIONS,
283+
stat: crate::index_as_worktree::TEST_OPTIONS,
251284
..Default::default()
252285
},
253286
dirwalk,
@@ -262,7 +295,7 @@ fn fixture_filtered_detailed(
262295
&worktree,
263296
&mut recorder,
264297
FastEq,
265-
crate::status::index_as_worktree::SubmoduleStatusMock { dirty: false },
298+
crate::index_as_worktree::SubmoduleStatusMock { dirty: false },
266299
objects,
267300
&mut gix_features::progress::Discard,
268301
context,

gix-status/tests/status/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
pub use gix_testtools::Result;
2+
13
mod index_as_worktree;
24
mod index_as_worktree_with_renames;
35

6+
mod stack;
7+
48
pub fn fixture_path(name: &str) -> std::path::PathBuf {
59
let dir = gix_testtools::scripted_fixture_read_only_standalone(std::path::Path::new(name).with_extension("sh"))
610
.expect("script works");
File renamed without changes.

gix-status/tests/worktree.rs

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)