#![allow(clippy::empty_docs)]
use gix_hash::ObjectId;
use gix_ref::FullNameRef;
use crate::{
ext::{ObjectIdExt, ReferenceExt},
Head,
};
#[derive(Clone)]
pub enum Kind {
Symbolic(gix_ref::Reference),
Unborn(gix_ref::FullName),
Detached {
target: ObjectId,
peeled: Option<ObjectId>,
},
}
impl Kind {
pub fn attach(self, repo: &crate::Repository) -> Head<'_> {
Head { kind: self, repo }
}
}
impl<'repo> Head<'repo> {
pub fn name(&self) -> &'static FullNameRef {
"HEAD".try_into().expect("HEAD is valid")
}
pub fn referent_name(&self) -> Option<&FullNameRef> {
Some(match &self.kind {
Kind::Symbolic(r) => r.name.as_ref(),
Kind::Unborn(name) => name.as_ref(),
Kind::Detached { .. } => return None,
})
}
pub fn is_detached(&self) -> bool {
matches!(self.kind, Kind::Detached { .. })
}
pub fn is_unborn(&self) -> bool {
matches!(self.kind, Kind::Unborn(_))
}
pub fn id(&self) -> Option<crate::Id<'repo>> {
match &self.kind {
Kind::Symbolic(r) => r.target.try_id().map(|oid| oid.to_owned().attach(self.repo)),
Kind::Detached { peeled, target } => {
(*peeled).unwrap_or_else(|| target.to_owned()).attach(self.repo).into()
}
Kind::Unborn(_) => None,
}
}
pub fn try_into_referent(self) -> Option<crate::Reference<'repo>> {
match self.kind {
Kind::Symbolic(r) => r.attach(self.repo).into(),
_ => None,
}
}
}
mod remote {
use super::Head;
use crate::{remote, Remote};
impl<'repo> Head<'repo> {
pub fn into_remote(
self,
direction: remote::Direction,
) -> Option<Result<Remote<'repo>, remote::find::existing::Error>> {
let repo = self.repo;
self.try_into_referent()?
.remote(direction)
.or_else(|| repo.find_default_remote(direction))
}
}
}
pub mod log;
pub mod peel;