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