1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//!

use git_odb::pack::Find;
use git_ref::file::ReferenceExt;

use crate::{
    easy,
    easy::{Oid, Reference},
};

pub mod iter;

mod errors;

pub use errors::{edit, find, peel};

use crate::ext::ObjectIdExt;

pub mod logs;

/// Access
impl<'repo> Reference<'repo> {
    /// Return the target to which this reference points to.
    pub fn target(&self) -> git_ref::TargetRef<'_> {
        self.inner.target.to_ref()
    }

    /// Return the reference's full name.
    pub fn name(&self) -> git_ref::FullNameRef<'_> {
        self.inner.name.to_ref()
    }

    /// Turn this instances into a stand-alone reference.
    pub fn detach(self) -> git_ref::Reference {
        self.inner
    }
}

impl<'repo> Reference<'repo> {
    pub(crate) fn from_ref(reference: git_ref::Reference, handle: &'repo easy::Handle) -> Self {
        Reference {
            inner: reference,
            handle,
        }
    }

    /// Returns the attached id we point to, or panic if this is a symbolic ref.
    pub fn id(&self) -> easy::Oid<'repo> {
        match self.inner.target {
            git_ref::Target::Symbolic(_) => panic!("BUG: tries to obtain object id from symbolic target"),
            git_ref::Target::Peeled(oid) => oid.to_owned().attach(self.handle),
        }
    }

    /// Follow all symbolic targets this reference might point to and peel the underlying object
    /// to the end of the chain, and return it.
    ///
    /// This is useful to learn where this reference is ulitmately pointing to.
    pub fn peel_to_id_in_place(&mut self) -> Result<Oid<'repo>, peel::Error> {
        let handle = &self.handle;
        let oid = self.inner.peel_to_id_in_place(&handle.refs, |oid, buf| {
            handle
                .objects
                .try_find(oid, buf)
                .map(|po| po.map(|(o, _l)| (o.kind, o.data)))
        })?;
        Ok(Oid::from_id(oid, handle))
    }

    /// Similar to [`peel_to_id_in_place()`][Reference::peel_to_id_in_place()], but consumes this instance.
    pub fn into_fully_peeled_id(mut self) -> Result<Oid<'repo>, peel::Error> {
        self.peel_to_id_in_place()
    }
}