summaryrefslogtreecommitdiffstats
path: root/vendor/gix-index/src/entry/flags.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-index/src/entry/flags.rs')
-rw-r--r--vendor/gix-index/src/entry/flags.rs130
1 files changed, 130 insertions, 0 deletions
diff --git a/vendor/gix-index/src/entry/flags.rs b/vendor/gix-index/src/entry/flags.rs
new file mode 100644
index 000000000..ec00a78db
--- /dev/null
+++ b/vendor/gix-index/src/entry/flags.rs
@@ -0,0 +1,130 @@
+use bitflags::bitflags;
+
+use crate::entry::Stage;
+
+bitflags! {
+ /// In-memory flags
+ pub struct Flags: u32 {
+ /// The mask to apply to obtain the stage number of an entry.
+ const STAGE_MASK = 0x3000;
+ /// If set, additional bits need to be written to storage.
+ const EXTENDED = 0x4000;
+ // TODO: could we use the pathlen ourselves to save 8 bytes? And how to handle longer paths than that? 0 as sentinel maybe?
+ /// The mask to obtain the length of the path associated with this entry.
+ const PATH_LEN = 0x0fff;
+ /// If set, the entry be assumed to match with the version on the working tree, as a way to avoid `lstat()` checks.
+ const ASSUME_VALID = 1 << 15;
+ /// Indicates that an entry needs to be updated as it's in-memory representation doesn't match what's on disk.
+ const UPDATE = 1 << 16;
+ /// Indicates an entry should be removed - this typically happens during writing, by simply skipping over them.
+ const REMOVE = 1 << 17;
+ /// Indicates that an entry is known to be uptodate.
+ const UPTODATE = 1 << 18;
+ /// Only temporarily used by unpack_trees() (in C)
+ const ADDED = 1 << 19;
+
+ /// Whether an up-to-date object hash exists for the entry.
+ const HASHED = 1 << 20;
+ /// Set if the filesystem monitor is valid.
+ const FSMONITOR_VALID = 1 << 21;
+ /// Remove in work directory
+ const WORKTREE_REMOVE = 1 << 22;
+ /// Set to indicate the entry exists in multiple stages at once due to conflicts.
+ const CONFLICTED = 1 << 23;
+
+ /// Indicates that the entry was already turned into a tree.
+ const UNPACKED = 1 << 24;
+ /// Only temporarily used by unpack_trees() (in C)
+ const NEW_SKIP_WORKTREE = 1 << 25;
+
+ /// temporarily mark paths matched by a path spec
+ const PATHSPEC_MATCHED = 1 << 26;
+
+ /// When the index is split, this indicates the entry is up-to-date in the shared portion of the index.
+ const UPDATE_IN_BASE = 1 << 27;
+ /// Indicates the entry name is present in the base/shared index, and thus doesn't have to be stored in this one.
+ const STRIP_NAME = 1 << 28;
+
+ ///
+ /// stored at rest, see at_rest::FlagsExtended
+ const INTENT_TO_ADD = 1 << 29;
+ /// Stored at rest
+ const SKIP_WORKTREE = 1 << 30;
+
+ /// For future extension
+ const EXTENDED_2 = 1 << 31;
+ }
+}
+
+impl Flags {
+ /// Return the stage as extracted from the bits of this instance.
+ pub fn stage(&self) -> Stage {
+ (*self & Flags::STAGE_MASK).bits >> 12
+ }
+
+ /// Transform ourselves to a storage representation to keep all flags which are to be persisted,
+ /// skipping all extended flags. Note that the caller has to check for the `EXTENDED` bit to be present
+ /// and write extended flags as well if so.
+ pub fn to_storage(mut self) -> at_rest::Flags {
+ at_rest::Flags::from_bits(
+ {
+ self.remove(Self::PATH_LEN);
+ self
+ }
+ .bits() as u16,
+ )
+ .unwrap()
+ }
+}
+
+pub(crate) mod at_rest {
+ use bitflags::bitflags;
+
+ bitflags! {
+ /// Flags how they are serialized to a storage location
+ pub struct Flags: u16 {
+ /// A portion of a the flags that encodes the length of the path that follows.
+ const PATH_LEN = 0x0fff;
+ const STAGE_MASK = 0x3000;
+ /// If set, there is more extended flags past this one
+ const EXTENDED = 0x4000;
+ /// If set, the entry be assumed to match with the version on the working tree, as a way to avoid `lstat()` checks.
+ const ASSUME_VALID = 0x8000;
+ }
+ }
+
+ impl Flags {
+ pub fn to_memory(self) -> super::Flags {
+ super::Flags::from_bits(self.bits as u32).expect("PATHLEN is part of memory representation")
+ }
+ }
+
+ bitflags! {
+ /// Extended flags - add flags for serialization here and offset them down to u16.
+ pub struct FlagsExtended: u16 {
+ const INTENT_TO_ADD = 1 << (29 - 16);
+ const SKIP_WORKTREE = 1 << (30 - 16);
+ }
+ }
+
+ impl FlagsExtended {
+ pub fn from_flags(flags: super::Flags) -> Self {
+ Self::from_bits(((flags & (super::Flags::INTENT_TO_ADD | super::Flags::SKIP_WORKTREE)).bits >> 16) as u16)
+ .expect("valid")
+ }
+ pub fn to_flags(self) -> Option<super::Flags> {
+ super::Flags::from_bits((self.bits as u32) << 16)
+ }
+ }
+
+ #[cfg(test)]
+ mod tests {
+ use super::*;
+
+ #[test]
+ fn flags_from_bits_with_conflict() {
+ let input = 0b1110_0010_1000_1011;
+ assert_eq!(Flags::from_bits(input).unwrap().bits, input);
+ }
+ }
+}