gix_ref/lib.rs
1//! A crate for handling the references stored in various formats in a git repository.
2//!
3//! References are also called _refs_ which are used interchangeably.
4//!
5//! Refs are the way to keep track of objects and come in two flavors.
6//!
7//! * symbolic refs are pointing to another reference
8//! * peeled refs point to the an object by its [`ObjectId`]
9//!
10//! They can be identified by a relative path and stored in various flavors.
11//!
12//! * **files**
13//! * **[loose][file::Store]**
14//! * one reference maps to a file on disk
15//! * **packed**
16//! * references are stored in a single human-readable file, along with their targets if they are symbolic.
17//!
18//! ## Feature Flags
19#![cfg_attr(
20 all(doc, feature = "document-features"),
21 doc = ::document_features::document_features!()
22)]
23#![cfg_attr(all(doc, feature = "document-features"), feature(doc_cfg))]
24#![deny(missing_docs, unsafe_code)]
25
26use gix_hash::{ObjectId, oid};
27pub use gix_object::bstr;
28use gix_object::bstr::{BStr, BString};
29
30#[path = "store/mod.rs"]
31mod store_impl;
32pub use store_impl::{file, packed};
33
34mod fullname;
35///
36pub mod name;
37///
38pub mod namespace;
39///
40pub mod transaction;
41
42mod parse;
43mod raw;
44
45pub use raw::Reference;
46
47mod target;
48
49///
50pub mod log;
51
52///
53pub mod peel;
54
55///
56pub mod store {
57 ///
58 pub mod init {
59
60 /// Options for use during [initialization](crate::file::Store::at).
61 #[derive(Debug, Copy, Clone, Default)]
62 pub struct Options {
63 /// How to write the ref-log.
64 pub write_reflog: super::WriteReflog,
65 /// The equivalent of `core.precomposeUnicode`.
66 pub precompose_unicode: bool,
67 /// If `true`, we will avoid reading from or writing to references that contains Windows device names
68 /// to avoid side effects. This only needs to be `true` on Windows, but can be `true` on other platforms
69 /// if they need to remain compatible with Windows.
70 pub prohibit_windows_device_names: bool,
71 }
72 }
73 /// The way a file store handles the reflog
74 #[derive(Default, Debug, PartialOrd, PartialEq, Ord, Eq, Hash, Clone, Copy)]
75 pub enum WriteReflog {
76 /// Always write the reflog for all references for ref edits, unconditionally.
77 Always,
78 /// Write a ref log for ref edits according to the standard rules.
79 #[default]
80 Normal,
81 /// Never write a ref log.
82 Disable,
83 }
84
85 /// A thread-local handle for interacting with a [`Store`][crate::Store] to find and iterate references.
86 #[derive(Clone)]
87 #[expect(
88 dead_code,
89 reason = "the general reference-store handle is scaffolding for planned ref-table support"
90 )]
91 pub(crate) struct Handle {
92 /// A way to access shared state with the requirement that interior mutability doesn't leak or is incorporated into error types
93 /// if it could. The latter can't happen if references to said internal aren't ever returned.
94 state: handle::State,
95 }
96
97 #[expect(
98 dead_code,
99 reason = "the general reference-store state is scaffolding for planned ref-table support"
100 )]
101 pub(crate) enum State {
102 Loose { store: file::Store },
103 }
104
105 pub(crate) mod general;
106
107 ///
108 #[path = "general/handle/mod.rs"]
109 mod handle;
110 pub use handle::find;
111
112 use crate::file;
113}
114
115/// The git reference store.
116/// TODO: Figure out if handles are needed at all, which depends on the ref-table implementation.
117#[expect(
118 dead_code,
119 reason = "callers still use file::Store directly while this general store awaits ref-table support"
120)]
121pub(crate) struct Store {
122 inner: store::State,
123}
124
125/// A validated complete and fully qualified reference name, safe to use for all operations.
126#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
127#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
128pub struct FullName(pub(crate) BString);
129
130/// A validated complete and fully qualified reference name, safe to use for all operations.
131#[derive(Hash, Debug, PartialEq, Eq, Ord, PartialOrd)]
132#[repr(transparent)]
133pub struct FullNameRef(BStr);
134
135/// A validated and potentially partial reference name, safe to use for common operations.
136#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
137#[repr(transparent)]
138pub struct PartialNameRef(BStr);
139
140/// A validated and potentially partial reference name, safe to use for common operations.
141#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
142#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
143pub struct PartialName(BString);
144
145/// A _validated_ prefix for references to act as a namespace.
146#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
147#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
148pub struct Namespace(BString);
149
150/// Denotes the kind of reference.
151#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
152#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
153pub enum Kind {
154 /// A ref that points to an object id directly.
155 Object,
156 /// A ref that points to another reference, adding a level of indirection.
157 ///
158 /// It can be resolved to an id using the [`peel_to_id()`][`crate::file::ReferenceExt::peel_to_id()`] method.
159 Symbolic,
160}
161
162/// The various known categories of references.
163///
164/// This translates into a prefix containing all references of a given category.
165#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
166#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
167pub enum Category<'a> {
168 /// A tag in `refs/tags`
169 Tag,
170 /// A branch in `refs/heads`
171 LocalBranch,
172 /// A branch in `refs/remotes`
173 RemoteBranch,
174 /// A tag in `refs/notes`
175 Note,
176 /// Something outside `ref/` in the current worktree, typically `HEAD`.
177 PseudoRef,
178 /// A `PseudoRef`, but referenced so that it will always refer to the main worktree by
179 /// prefixing it with `main-worktree/`.
180 MainPseudoRef,
181 /// Any reference that is prefixed with `main-worktree/refs/`
182 MainRef,
183 /// A `PseudoRef` in another _linked_ worktree, never in the main one, like `worktrees/<id>/HEAD`.
184 LinkedPseudoRef {
185 /// The name of the worktree.
186 #[cfg_attr(feature = "serde", serde(borrow))]
187 name: &'a BStr,
188 },
189 /// Any reference that is prefixed with `worktrees/<id>/refs/`.
190 LinkedRef {
191 /// The name of the worktree.
192 name: &'a BStr,
193 },
194 /// A ref that is private to each worktree (_linked_ or _main_), with `refs/bisect/` prefix
195 Bisect,
196 /// A ref that is private to each worktree (_linked_ or _main_), with `refs/rewritten/` prefix
197 Rewritten,
198 /// A ref that is private to each worktree (_linked_ or _main_), with `refs/worktree/` prefix
199 WorktreePrivate,
200 // REF_TYPE_NORMAL, /* normal/shared refs inside refs/ */
201}
202
203/// Denotes a ref target, equivalent to [`Kind`], but with mutable data.
204#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
205#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
206pub enum Target {
207 /// A ref that points directly to an object id.
208 Object(ObjectId),
209 /// A ref that points to another reference by its validated name, adding a level of indirection.
210 ///
211 /// Note that this is an extension of gitoxide which will be helpful in logging all reference changes.
212 Symbolic(FullName),
213}
214
215/// Denotes a ref target, equivalent to [`Kind`], but with immutable data.
216#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
217pub enum TargetRef<'a> {
218 /// A ref that points directly to an object id.
219 Object(&'a oid),
220 /// A ref that points to another reference by its validated name, adding a level of indirection.
221 Symbolic(&'a FullNameRef),
222}