blob: aadd087ba3ce0f1b0a5b499762542f2b608a45fb [file] [log] [blame]
Charisee635618d2023-06-01 20:46:00 +00001///
2pub mod set_target_id {
3 use gix_ref::{transaction::PreviousValue, Target};
4
5 use crate::{bstr::BString, Reference};
6
7 mod error {
8 use gix_ref::FullName;
9
10 /// The error returned by [`Reference::set_target_id()`][super::Reference::set_target_id()].
11 #[derive(Debug, thiserror::Error)]
12 #[allow(missing_docs)]
13 pub enum Error {
14 #[error("Cannot change symbolic reference {name:?} into a direct one by setting it to an id")]
15 SymbolicReference { name: FullName },
16 #[error(transparent)]
17 ReferenceEdit(#[from] crate::reference::edit::Error),
18 }
19 }
20 pub use error::Error;
21
22 impl<'repo> Reference<'repo> {
23 /// Set the id of this direct reference to `id` and use `reflog_message` for the reflog (if enabled in the repository).
24 ///
25 /// Note that the operation will fail on symbolic references, to change their type use the lower level reference database,
26 /// or if the reference was deleted or changed in the mean time.
27 /// Furthermore, refrain from using this method for more than a one-off change as it creates a transaction for each invocation.
28 /// If multiple reference should be changed, use [Repository::edit_references()][crate::Repository::edit_references()]
29 /// or the lower level reference database instead.
30 #[allow(clippy::result_large_err)]
31 pub fn set_target_id(
32 &mut self,
33 id: impl Into<gix_hash::ObjectId>,
34 reflog_message: impl Into<BString>,
35 ) -> Result<(), Error> {
36 match &self.inner.target {
37 Target::Symbolic(name) => return Err(Error::SymbolicReference { name: name.clone() }),
38 Target::Peeled(current_id) => {
39 let changed = self.repo.reference(
40 self.name(),
41 id,
42 PreviousValue::MustExistAndMatch(Target::Peeled(current_id.to_owned())),
43 reflog_message,
44 )?;
45 *self = changed;
46 }
47 }
48 Ok(())
49 }
50 }
51}
52
53///
54pub mod delete {
55 use gix_ref::transaction::{Change, PreviousValue, RefEdit, RefLog};
56
57 use crate::Reference;
58
59 impl<'repo> Reference<'repo> {
60 /// Delete this reference or fail if it was changed since last observed.
61 /// Note that this instance remains available in memory but probably shouldn't be used anymore.
62 pub fn delete(&self) -> Result<(), crate::reference::edit::Error> {
63 self.repo
64 .edit_reference(RefEdit {
65 change: Change::Delete {
66 expected: PreviousValue::MustExistAndMatch(self.inner.target.clone()),
67 log: RefLog::AndReference,
68 },
69 name: self.inner.name.clone(),
70 deref: false,
71 })
72 .map(|_| ())
73 }
74 }
75}