Skip to content

Commit f3b76d0

Browse files
committed
fix: Replacing a directory with non-directory will not cause an error anymore (#1735).
1 parent 3f6ee52 commit f3b76d0

File tree

4 files changed

+46
-4
lines changed

4 files changed

+46
-4
lines changed

gix-status/src/index_as_worktree/function.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,10 @@ impl<'index> State<'_, 'index> {
356356
{
357357
let worktree_path = match self.path_stack.verified_path(gix_path::from_bstr(rela_path).as_ref()) {
358358
Ok(path) => path,
359-
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(Some(Change::Removed.into())),
360-
Err(err) => return Err(Error::Io(err)),
359+
Err(err) if gix_fs::io_err::is_not_found(err.kind(), err.raw_os_error()) => {
360+
return Ok(Some(Change::Removed.into()))
361+
}
362+
Err(err) => return Err(err.into()),
361363
};
362364
self.symlink_metadata_calls.fetch_add(1, Ordering::Relaxed);
363365
let metadata = match gix_index::fs::Metadata::from_path_no_follow(worktree_path) {
@@ -379,7 +381,9 @@ impl<'index> State<'_, 'index> {
379381
}
380382
}
381383
Ok(metadata) => metadata,
382-
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(Some(Change::Removed.into())),
384+
Err(err) if gix_fs::io_err::is_not_found(err.kind(), err.raw_os_error()) => {
385+
return Ok(Some(Change::Removed.into()))
386+
}
383387
Err(err) => {
384388
return Err(err.into());
385389
}
@@ -539,7 +543,7 @@ where
539543
// conversion to bstr can never fail because symlinks are only used
540544
// on unix (by git) so no reason to use the try version here
541545
let symlink_path =
542-
gix_path::to_unix_separators_on_windows(gix_path::into_bstr(std::fs::read_link(self.path)?));
546+
gix_path::to_unix_separators_on_windows(gix_path::into_bstr(std::fs::read_link(self.path).unwrap()));
543547
self.buf.extend_from_slice(&symlink_path);
544548
self.worktree_bytes.fetch_add(self.buf.len() as u64, Ordering::Relaxed);
545549
Stream {
Binary file not shown.

gix-status/tests/fixtures/status_many.sh

+13
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,16 @@ cp -R changed-and-untracked changed-and-untracked-and-renamed
3939
echo change >> content-with-rewrite
4040

4141
)
42+
43+
cp -R changed-and-untracked replace-dir-with-file
44+
(cd replace-dir-with-file
45+
git checkout executable
46+
rm untracked dir/untracked
47+
48+
mkdir dir/sub
49+
touch dir/sub/nested
50+
git add dir && git commit -m "add file in sub-directory"
51+
52+
rm -Rf dir/
53+
touch dir
54+
)

gix-status/tests/status/index_as_worktree.rs

+25
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,31 @@ fn removed() {
243243
);
244244
}
245245

246+
#[test]
247+
fn replace_dir_with_file() {
248+
let out = fixture_filtered_detailed(
249+
"status_many",
250+
"replace-dir-with-file",
251+
&[],
252+
&[
253+
(BStr::new(b"dir/content"), 0, status_removed()),
254+
(BStr::new(b"dir/content2"), 1, status_removed()),
255+
(BStr::new(b"dir/sub/nested"), 2, status_removed()),
256+
],
257+
|_| {},
258+
false,
259+
);
260+
assert_eq!(
261+
out,
262+
Outcome {
263+
entries_to_process: 5,
264+
entries_processed: 5,
265+
symlink_metadata_calls: if cfg!(windows) { 5 } else { 4 },
266+
..Default::default()
267+
}
268+
);
269+
}
270+
246271
#[test]
247272
fn subomdule_nochange() {
248273
assert_eq!(

0 commit comments

Comments
 (0)