#![allow(missing_docs)]use std::ops::DerefMut; use git_hash::ObjectId;use git_odb::Find;use git_ref as refs; use crate::{ easy, easy::{Oid, Reference},}; pub(crate) enum Backing { OwnedPacked { /// The validated full name of the reference. name: refs::FullName, /// The target object id of the reference, hex encoded. target: ObjectId, /// The fully peeled object id, hex encoded, that the ref is ultimately pointing to /// i.e. when all indirections are removed. object: Option<ObjectId>, }, LooseFile(refs::file::loose::Reference),} pub mod edit { use git_ref as refs; use quick_error::quick_error; use crate::easy; quick_error! { #[derive(Debug)] pub enum Error { FileTransactionPrepare(err: refs::file::transaction::prepare::Error) { display("Could not prepare the file transaction") from() source(err) } FileTransactionCommit(err: refs::file::transaction::commit::Error) { display("Could not commit the file transaction") from() source(err) } NameValidation(err: git_validate::reference::name::Error) { display("The reference name is invalid") from() source(err) } BorrowRepo(err: easy::borrow::repo::Error) { display("BUG: The repository could not be borrowed") from() } } }} pub mod peel_to_oid_in_place { use git_ref as refs; use quick_error::quick_error; use crate::easy; quick_error! { #[derive(Debug)] pub enum Error { LoosePeelToId(err: refs::file::loose::reference::peel::to_id::Error) { display("Could not peel loose reference") from() source(err) } PackedRefsOpen(err: refs::packed::buffer::open::Error) { display("The packed-refs file could not be opened") from() source(err) } BorrowState(err: easy::borrow::state::Error) { display("BUG: Part of interior state could not be borrowed.") from() source(err) } BorrowRepo(err: easy::borrow::repo::Error) { display("BUG: The repository could not be borrowed") from() } } }} // TODO: think about how to detach a Reference. It should essentially be a 'Raw' reference that should exist in `git-ref` rather than here.impl<'repo, A> Reference<'repo, A>where A: easy::Access + Sized,{ pub(crate) fn from_file_ref(reference: refs::file::Reference<'_>, access: &'repo A) -> Self { Reference { backing: match reference { refs::file::Reference::Packed(p) => Backing::OwnedPacked { name: p.name.into(), target: p.target(), object: p .object .map(|hex| ObjectId::from_hex(hex).expect("a hash kind we know")), }, refs::file::Reference::Loose(l) => Backing::LooseFile(l), } .into(), access, } } pub fn target(&self) -> refs::Target { match self.backing.as_ref().expect("always set") { Backing::OwnedPacked { target, .. } => refs::Target::Peeled(target.to_owned()), Backing::LooseFile(r) => r.target.clone(), } } pub fn name(&self) -> refs::FullNameRef<'_> { match self.backing.as_ref().expect("always set") { Backing::OwnedPacked { name, .. } => name, Backing::LooseFile(r) => &r.name, } .to_ref() } pub fn peel_to_oid_in_place(&mut self) -> Result<Oid<'repo, A>, peel_to_oid_in_place::Error> { let repo = self.access.repo()?; match self.backing.take().expect("a ref must be set") { Backing::LooseFile(mut r) => { let state = self.access.state(); let mut pack_cache = state.try_borrow_mut_pack_cache()?; let oid = r .peel_to_id_in_place( &repo.refs, state.assure_packed_refs_uptodate(&repo.refs)?.as_ref(), |oid, buf| { repo.odb .try_find(oid, buf, pack_cache.deref_mut()) .map(|po| po.map(|o| (o.kind, o.data))) }, )? .to_owned(); self.backing = Backing::LooseFile(r).into(); Ok(Oid::from_id(oid, self.access)) } Backing::OwnedPacked { mut target, mut object, name, } => { if let Some(peeled_id) = object.take() { target = peeled_id; } self.backing = Backing::OwnedPacked { name, target, object: None, } .into(); Ok(Oid::from_id(target, self.access)) } } }} pub mod find { use git_ref as refs; use quick_error::quick_error; use crate::easy; pub mod existing { use quick_error::quick_error; use crate::easy::reference::find; quick_error! { #[derive(Debug)] pub enum Error { Find(err: find::Error) { display("An error occurred when trying to find a reference") from() source(err) } NotFound { display("The reference did not exist even though that was expected") } } } } quick_error! { #[derive(Debug)] pub enum Error { Find(err: refs::file::find::Error) { display("An error occurred when trying to find a reference") from() source(err) } PackedRefsOpen(err: refs::packed::buffer::open::Error) { display("The packed-refs file could not be opened") from() source(err) } BorrowState(err: easy::borrow::state::Error) { display("BUG: Part of interior state could not be borrowed.") from() source(err) } BorrowRepo(err: easy::borrow::repo::Error) { display("BUG: The repository could not be borrowed") from() } } }}
#![allow(missing_docs)]
use std::ops::DerefMut;
use git_hash::ObjectId;
use git_odb::Find;
use git_ref as refs;
use crate::{
easy,
easy::{Oid, Reference},
};
pub(crate) enum Backing {
OwnedPacked {
/// The validated full name of the reference.
name: refs::FullName,
/// The target object id of the reference, hex encoded.
target: ObjectId,
/// The fully peeled object id, hex encoded, that the ref is ultimately pointing to
/// i.e. when all indirections are removed.
object: Option<ObjectId>,
},
LooseFile(refs::file::loose::Reference),
}
pub mod edit {
use git_ref as refs;
use quick_error::quick_error;
use crate::easy;
quick_error! {
#[derive(Debug)]
pub enum Error {
FileTransactionPrepare(err: refs::file::transaction::prepare::Error) {
display("Could not prepare the file transaction")
from()
source(err)
}
FileTransactionCommit(err: refs::file::transaction::commit::Error) {
display("Could not commit the file transaction")
from()
source(err)
}
NameValidation(err: git_validate::reference::name::Error) {
display("The reference name is invalid")
from()
source(err)
}
BorrowRepo(err: easy::borrow::repo::Error) {
display("BUG: The repository could not be borrowed")
from()
}
}
}
}
pub mod peel_to_oid_in_place {
use git_ref as refs;
use quick_error::quick_error;
use crate::easy;
quick_error! {
#[derive(Debug)]
pub enum Error {
LoosePeelToId(err: refs::file::loose::reference::peel::to_id::Error) {
display("Could not peel loose reference")
from()
source(err)
}
PackedRefsOpen(err: refs::packed::buffer::open::Error) {
display("The packed-refs file could not be opened")
from()
source(err)
}
BorrowState(err: easy::borrow::state::Error) {
display("BUG: Part of interior state could not be borrowed.")
from()
source(err)
}
BorrowRepo(err: easy::borrow::repo::Error) {
display("BUG: The repository could not be borrowed")
from()
}
}
}
}
// TODO: think about how to detach a Reference. It should essentially be a 'Raw' reference that should exist in `git-ref` rather than here.
impl<'repo, A> Reference<'repo, A>
where
A: easy::Access + Sized,
{
pub(crate) fn from_file_ref(reference: refs::file::Reference<'_>, access: &'repo A) -> Self {
Reference {
backing: match reference {
refs::file::Reference::Packed(p) => Backing::OwnedPacked {
name: p.name.into(),
target: p.target(),
object: p
.object
.map(|hex| ObjectId::from_hex(hex).expect("a hash kind we know")),
},
refs::file::Reference::Loose(l) => Backing::LooseFile(l),
}
.into(),
access,
}
}
pub fn target(&self) -> refs::Target {
match self.backing.as_ref().expect("always set") {
Backing::OwnedPacked { target, .. } => refs::Target::Peeled(target.to_owned()),
Backing::LooseFile(r) => r.target.clone(),
}
}
pub fn name(&self) -> refs::FullNameRef<'_> {
match self.backing.as_ref().expect("always set") {
Backing::OwnedPacked { name, .. } => name,
Backing::LooseFile(r) => &r.name,
}
.to_ref()
}
pub fn peel_to_oid_in_place(&mut self) -> Result<Oid<'repo, A>, peel_to_oid_in_place::Error> {
let repo = self.access.repo()?;
match self.backing.take().expect("a ref must be set") {
Backing::LooseFile(mut r) => {
let state = self.access.state();
let mut pack_cache = state.try_borrow_mut_pack_cache()?;
let oid = r
.peel_to_id_in_place(
&repo.refs,
state.assure_packed_refs_uptodate(&repo.refs)?.as_ref(),
|oid, buf| {
repo.odb
.try_find(oid, buf, pack_cache.deref_mut())
.map(|po| po.map(|o| (o.kind, o.data)))
},
)?
.to_owned();
self.backing = Backing::LooseFile(r).into();
Ok(Oid::from_id(oid, self.access))
}
Backing::OwnedPacked {
mut target,
mut object,
name,
} => {
if let Some(peeled_id) = object.take() {
target = peeled_id;
}
self.backing = Backing::OwnedPacked {
name,
target,
object: None,
}
.into();
Ok(Oid::from_id(target, self.access))
}
}
}
}
pub mod find {
use git_ref as refs;
use quick_error::quick_error;
use crate::easy;
pub mod existing {
use quick_error::quick_error;
use crate::easy::reference::find;
quick_error! {
#[derive(Debug)]
pub enum Error {
Find(err: find::Error) {
display("An error occurred when trying to find a reference")
from()
source(err)
}
NotFound {
display("The reference did not exist even though that was expected")
}
}
}
}
quick_error! {
#[derive(Debug)]
pub enum Error {
Find(err: refs::file::find::Error) {
display("An error occurred when trying to find a reference")
from()
source(err)
}
PackedRefsOpen(err: refs::packed::buffer::open::Error) {
display("The packed-refs file could not be opened")
from()
source(err)
}
BorrowState(err: easy::borrow::state::Error) {
display("BUG: Part of interior state could not be borrowed.")
from()
source(err)
}
BorrowRepo(err: easy::borrow::repo::Error) {
display("BUG: The repository could not be borrowed")
from()
}
}
}
}