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