gix_index/entry/mod.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
/// The stage of an entry.
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub enum Stage {
/// This is the default, and most entries are in this stage.
#[default]
Unconflicted = 0,
/// The entry is the common base between 'our' change and 'their' change, for comparison.
Base = 1,
/// The entry represents our change.
Ours = 2,
/// The entry represents their change.
Theirs = 3,
}
// The stage of an entry, one of…
/// * 0 = no conflict,
/// * 1 = base,
/// * 2 = ours,
/// * 3 = theirs
pub type StageRaw = u32;
///
pub mod mode;
mod flags;
pub(crate) use flags::at_rest;
pub use flags::Flags;
///
pub mod stat;
mod write;
use bitflags::bitflags;
bitflags! {
/// The kind of file of an entry.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Mode: u32 {
/// directory (only used for sparse checkouts), equivalent to a tree, which is _excluded_ from the index via
/// cone-mode.
const DIR = 0o040000;
/// regular file
const FILE = 0o100644;
/// regular file, executable
const FILE_EXECUTABLE = 0o100755;
/// Symbolic link
const SYMLINK = 0o120000;
/// A git commit for submodules
const COMMIT = 0o160000;
}
}
/// An entry's filesystem stat information.
#[derive(Debug, Default, PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Stat {
/// Modification time
pub mtime: stat::Time,
/// Creation time
pub ctime: stat::Time,
/// Device number
pub dev: u32,
/// Inode number
pub ino: u32,
/// User id of the owner
pub uid: u32,
/// Group id of the owning group
pub gid: u32,
/// The size of bytes on disk. Capped to u32 so files bigger than that will need thorough additional checking
pub size: u32,
}
mod access {
use bstr::{BStr, ByteSlice};
use crate::{entry, Entry, State};
impl Entry {
/// Return an entry's path, relative to the repository, which is extracted from its owning `state`.
pub fn path<'a>(&self, state: &'a State) -> &'a BStr {
state.path_backing[self.path.clone()].as_bstr()
}
/// Return an entry's path using the given `backing`.
pub fn path_in<'backing>(&self, backing: &'backing crate::PathStorageRef) -> &'backing BStr {
backing[self.path.clone()].as_bstr()
}
/// Return an entry's stage. See [entry::Stage] for possible values.
pub fn stage(&self) -> entry::Stage {
self.flags.stage()
}
/// Return an entry's stage as raw number between 0 and 4.
/// Possible values are:
///
/// * 0 = no conflict,
/// * 1 = base,
/// * 2 = ours,
/// * 3 = theirs
pub fn stage_raw(&self) -> u32 {
self.flags.stage_raw()
}
}
}
mod _impls {
use std::cmp::Ordering;
use bstr::BStr;
use crate::{Entry, State};
impl Entry {
/// Compare one entry to another by their path, by comparing only their common path portion byte by byte, then resorting to
/// entry length and stage.
pub fn cmp(&self, other: &Self, state: &State) -> Ordering {
let lhs = self.path(state);
let rhs = other.path(state);
Entry::cmp_filepaths(lhs, rhs).then_with(|| self.stage().cmp(&other.stage()))
}
/// Compare one entry to another by their path, by comparing only their common path portion byte by byte, then resorting to
/// entry length.
pub fn cmp_filepaths(a: &BStr, b: &BStr) -> Ordering {
let common_len = a.len().min(b.len());
a[..common_len]
.cmp(&b[..common_len])
.then_with(|| a.len().cmp(&b.len()))
}
}
}