From 18b2a97544d779694ff3cdb27734513547d1cec2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 15 Jan 2025 16:09:10 +0100 Subject: [PATCH 1/4] Slightly improve docs of `entry::Mode::change_to_match_fs()` --- gix-index/src/entry/mod.rs | 2 +- gix-index/src/entry/mode.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gix-index/src/entry/mod.rs b/gix-index/src/entry/mod.rs index 258fb0949dd..3f5ba509b27 100644 --- a/gix-index/src/entry/mod.rs +++ b/gix-index/src/entry/mod.rs @@ -34,7 +34,7 @@ use bitflags::bitflags; bitflags! { /// The kind of file of an entry. - #[derive(Copy, Clone, Debug, PartialEq, Eq)] + #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] pub struct Mode: u32 { /// directory (only used for sparse checkouts), equivalent to a tree, which is _excluded_ from the index via /// cone-mode. diff --git a/gix-index/src/entry/mode.rs b/gix-index/src/entry/mode.rs index 4604d08d62c..6221287824f 100644 --- a/gix-index/src/entry/mode.rs +++ b/gix-index/src/entry/mode.rs @@ -28,9 +28,9 @@ impl Mode { /// If there is a type change then we will use whatever information is /// present on the FS. Specifically if `has_symlinks` is false we will /// never generate `Change::TypeChange { new_mode: Mode::SYMLINK }`. and - /// iff `executable_bit` is false we will never generate `Change::TypeChange + /// if `executable_bit` is false we will never generate `Change::TypeChange /// { new_mode: Mode::FILE_EXECUTABLE }` (all files are assumed to be not - /// executable). That measn that unstaging and staging files can be a lossy + /// executable). That means that unstaging and staging files can be a lossy /// operation on such file systems. /// /// If a directory replaced a normal file/symlink we assume that the From 77ecdb5888b4e0ba20862fb606f8f897900ccf5c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 14 Jan 2025 20:54:07 +0100 Subject: [PATCH 2/4] fix!: let the `Change::Type` carry the new type. Previously it would just discard that information. --- gix-status/src/index_as_worktree/function.rs | 9 ++- gix-status/src/index_as_worktree/types.rs | 6 +- .../src/index_as_worktree_with_renames/mod.rs | 2 +- .../index_as_worktree_with_renames/types.rs | 2 +- gix-status/tests/status/index_as_worktree.rs | 64 ++++++++++++++++--- .../status/index_as_worktree_with_renames.rs | 8 ++- 6 files changed, 77 insertions(+), 14 deletions(-) diff --git a/gix-status/src/index_as_worktree/function.rs b/gix-status/src/index_as_worktree/function.rs index 1affadb1c22..c6edc032d69 100644 --- a/gix-status/src/index_as_worktree/function.rs +++ b/gix-status/src/index_as_worktree/function.rs @@ -397,7 +397,14 @@ impl<'index> State<'_, 'index> { .mode .change_to_match_fs(&metadata, self.options.fs.symlink, self.options.fs.executable_bit) { - Some(gix_index::entry::mode::Change::Type { .. }) => return Ok(Some(Change::Type.into())), + Some(gix_index::entry::mode::Change::Type { new_mode }) => { + return Ok(Some( + Change::Type { + worktree_mode: new_mode, + } + .into(), + )) + } Some(gix_index::entry::mode::Change::ExecutableBit) => true, None => false, }; diff --git a/gix-status/src/index_as_worktree/types.rs b/gix-status/src/index_as_worktree/types.rs index 80554a77f38..f38f131e74d 100644 --- a/gix-status/src/index_as_worktree/types.rs +++ b/gix-status/src/index_as_worktree/types.rs @@ -111,7 +111,11 @@ pub enum Change { /// /// A change to a non-file is marked as `modification` in Git, but that's related to the content which we can't evaluate. /// Hence, a type-change is considered more appropriate. - Type, + Type { + /// The mode the worktree file would have if it was added to the index, and the mode that differs compared + /// to what's currently stored in the index. + worktree_mode: gix_index::entry::Mode, + }, /// This worktree file was modified in some form, like a permission change or content change or both, /// as compared to this entry. Modification { diff --git a/gix-status/src/index_as_worktree_with_renames/mod.rs b/gix-status/src/index_as_worktree_with_renames/mod.rs index 6ce99b1a7bf..8368102c246 100644 --- a/gix-status/src/index_as_worktree_with_renames/mod.rs +++ b/gix-status/src/index_as_worktree_with_renames/mod.rs @@ -455,7 +455,7 @@ pub(super) mod function { } EntryStatus::Change(c) => match c { Change::Removed => ChangeKind::Deletion, - Change::Type | Change::Modification { .. } | Change::SubmoduleModification(_) => { + Change::Type { .. } | Change::Modification { .. } | Change::SubmoduleModification(_) => { ChangeKind::Modification } }, diff --git a/gix-status/src/index_as_worktree_with_renames/types.rs b/gix-status/src/index_as_worktree_with_renames/types.rs index dbfdefc8a98..ccf17feaf0f 100644 --- a/gix-status/src/index_as_worktree_with_renames/types.rs +++ b/gix-status/src/index_as_worktree_with_renames/types.rs @@ -230,7 +230,7 @@ impl Entry<'_, ContentChange, SubmoduleStatus> { .. } => match change { Change::SubmoduleModification(_) | Change::Modification { .. } => Summary::Modified, - Change::Type => Summary::TypeChange, + Change::Type { .. } => Summary::TypeChange, Change::Removed => Summary::Removed, }, Entry::DirectoryContents { entry, .. } => { diff --git a/gix-status/tests/status/index_as_worktree.rs b/gix-status/tests/status/index_as_worktree.rs index 3544aedccfc..ff5e7ee5668 100644 --- a/gix-status/tests/status/index_as_worktree.rs +++ b/gix-status/tests/status/index_as_worktree.rs @@ -7,7 +7,7 @@ use bstr::BStr; use filetime::{set_file_mtime, FileTime}; use gix_filter::eol::AutoCrlf; use gix_index as index; -use gix_index::Entry; +use gix_index::{entry, Entry}; use gix_status::index_as_worktree::Context; use gix_status::{ index_as_worktree, @@ -231,7 +231,7 @@ fn deracify_status(status: EntryStatus) -> Option { EntryStatus::Conflict(c) => EntryStatus::Conflict(c), EntryStatus::Change(c) => match c { Change::Removed => Change::Removed, - Change::Type => Change::Type, + Change::Type { worktree_mode } => Change::Type { worktree_mode }, Change::Modification { executable_bit_changed, content_change, @@ -284,7 +284,17 @@ fn nonfile_untracked_are_not_visible() { #[test] #[cfg(unix)] fn tracked_changed_to_non_file() { - nonfile_fixture("tracked-swapped", &[(BStr::new(b"file"), 0, Change::Type.into())]); + nonfile_fixture( + "tracked-swapped", + &[( + BStr::new(b"file"), + 0, + Change::Type { + worktree_mode: entry::Mode::FILE, + } + .into(), + )], + ); } #[test] @@ -384,7 +394,17 @@ fn subomdule_deleted_dir() { #[test] fn subomdule_typechange() { assert_eq!( - submodule_fixture("type-change", &[(BStr::new(b"m1"), 1, Change::Type.into())]), + submodule_fixture( + "type-change", + &[( + BStr::new(b"m1"), + 1, + Change::Type { + worktree_mode: entry::Mode::FILE + } + .into() + )] + ), Outcome { entries_to_process: 2, entries_processed: 2, @@ -596,7 +616,14 @@ fn refresh() { } .into(), ), - (BStr::new(b"empty"), 3, Change::Type.into()), + ( + BStr::new(b"empty"), + 3, + Change::Type { + worktree_mode: entry::Mode::FILE + } + .into() + ), ( BStr::new(b"executable"), 4, @@ -620,7 +647,14 @@ fn refresh() { } .into(), ), - (BStr::new("empty"), 3, Change::Type.into()), + ( + BStr::new("empty"), + 3, + Change::Type { + worktree_mode: entry::Mode::FILE + } + .into() + ), ( BStr::new("executable"), 4, @@ -669,7 +703,14 @@ fn modified() { } .into(), ), - (BStr::new(b"empty"), 3, Change::Type.into()), + ( + BStr::new(b"empty"), + 3, + Change::Type { + worktree_mode: entry::Mode::FILE, + } + .into(), + ), ( BStr::new(b"executable"), 4, @@ -693,7 +734,14 @@ fn modified() { } .into(), ), - (BStr::new("empty"), 3, Change::Type.into()), + ( + BStr::new("empty"), + 3, + Change::Type { + worktree_mode: entry::Mode::FILE, + } + .into(), + ), ( BStr::new("executable"), 4, diff --git a/gix-status/tests/status/index_as_worktree_with_renames.rs b/gix-status/tests/status/index_as_worktree_with_renames.rs index 5ed86f41213..468cbf4322b 100644 --- a/gix-status/tests/status/index_as_worktree_with_renames.rs +++ b/gix-status/tests/status/index_as_worktree_with_renames.rs @@ -2,6 +2,7 @@ use crate::fixture_path; use bstr::ByteSlice; use gix_diff::blob::pipeline::WorktreeRoots; use gix_diff::rewrites::CopySource; +use gix_index::entry; use gix_status::index_as_worktree::traits::FastEq; use gix_status::index_as_worktree::{Change, EntryStatus}; use gix_status::index_as_worktree_with_renames; @@ -123,7 +124,10 @@ fn tracked_changed_to_non_file() { &[], &[Expectation::Modification { rela_path: "file", - status: Change::Type.into(), + status: Change::Type { + worktree_mode: entry::Mode::FILE, + } + .into(), }], None, Some(Default::default()), @@ -393,7 +397,7 @@ impl Expectation<'_> { EntryStatus::Conflict(_) => Summary::Conflict, EntryStatus::Change(change) => match change { Change::Removed => Summary::Removed, - Change::Type => Summary::TypeChange, + Change::Type { .. } => Summary::TypeChange, Change::Modification { .. } | Change::SubmoduleModification(_) => Summary::Modified, }, EntryStatus::NeedsUpdate(_) => return None, From 25d480c1e48ffc89431cbdddb1e028c8d399e6d9 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 15 Jan 2025 16:46:32 +0100 Subject: [PATCH 3/4] adapt to changes in `gix-status` --- gitoxide-core/src/repository/status.rs | 2 +- gix/src/status/index_worktree.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gitoxide-core/src/repository/status.rs b/gitoxide-core/src/repository/status.rs index ab2812a6407..9804dfa214c 100644 --- a/gitoxide-core/src/repository/status.rs +++ b/gitoxide-core/src/repository/status.rs @@ -249,7 +249,7 @@ fn change_to_char(change: &Change<(), gix::submodule::Status>) -> u8 { // Known status letters: https://github.com/git/git/blob/6807fcfedab84bc8cd0fbf721bc13c4e68cda9ae/diff.h#L613 match change { Change::Removed => b'D', - Change::Type => b'T', + Change::Type { .. } => b'T', Change::SubmoduleModification(_) => b'M', Change::Modification { executable_bit_changed, .. diff --git a/gix/src/status/index_worktree.rs b/gix/src/status/index_worktree.rs index 71ae3b0c1ce..0a5ba17f2d4 100644 --- a/gix/src/status/index_worktree.rs +++ b/gix/src/status/index_worktree.rs @@ -462,7 +462,7 @@ pub mod iter { EntryStatus::Conflict(_) => Conflict, EntryStatus::Change(change) => match change { Change::Removed => Removed, - Change::Type => TypeChange, + Change::Type { .. } => TypeChange, Change::Modification { .. } | Change::SubmoduleModification(_) => Modified, }, EntryStatus::NeedsUpdate(_) => return None, From a661a8a0ab94f956f9036dd41a87ed46a8282bfe Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 15 Jan 2025 18:13:08 +0100 Subject: [PATCH 4/4] deactivate fuzzing as it's not building anymore for unrelated reasons --- .github/workflows/cifuzz.yml | 46 ------------------------------------ 1 file changed, 46 deletions(-) delete mode 100644 .github/workflows/cifuzz.yml diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml deleted file mode 100644 index 6f6c70b39a4..00000000000 --- a/.github/workflows/cifuzz.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: CIFuzz - -on: - pull_request: - branches: - - main - paths: - - '.github/**' - - 'ci/**' - - 'etc/**' - - 'src/**' - - 'tests/**' - - 'cargo-*/**' - - 'gix*/**' - - '*.toml' - - Makefile - workflow_dispatch: - -jobs: - Fuzzing: - runs-on: ubuntu-latest - - permissions: - contents: none # The fuzzing actions don't use our github.token at all. - - steps: - - name: Build Fuzzers - id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: gitoxide - language: rust - - - name: Run Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master - with: - oss-fuzz-project-name: gitoxide - language: rust - fuzz-seconds: 600 - - - name: Upload Crash - uses: actions/upload-artifact@v4 - if: failure() && steps.build.outcome == 'success' - with: - name: artifacts - path: ./out/artifacts