Unified · Split
| @@ -985,7 +985,7 @@ dependencies = [ · 984 unmodified lines | |||
| 985 | 985 | ||
| 986 | [[package]] | 986 | [[package]] |
| 987 | name = "git-actor" | 987 | name = "git-actor" |
| 988 | version = "0.4.0" | 988 | version = "0.5.0" |
| 989 | dependencies = [ | 989 | dependencies = [ |
| 990 | "bstr", | 990 | "bstr", |
| 991 | "btoi", | 991 | "btoi", |
| @@ -141,7 +141,7 @@ pub(in crate::command::release_impl) fn create_version_tag<'repo>( · 140 unmodified lines | |||
| 141 | skip_tag, | 141 | skip_tag, |
| 142 | .. | 142 | .. |
| 143 | }: Options, | 143 | }: Options, |
| 144 | ) -> anyhow::Result<Option<refs::mutable::FullName>> { | 144 | ) -> anyhow::Result<Option<refs::FullName>> { |
| 145 | if skip_tag { | 145 | if skip_tag { |
| 146 | return Ok(None); | 146 | return Ok(None); |
| 147 | } | 147 | } |
| @@ -170,10 +170,7 @@ pub(in crate::command::release_impl) fn create_version_tag<'repo>( · 22 unmodified lines | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | // TODO: Make this gitoxide | 172 | // TODO: Make this gitoxide |
| 173 | pub fn push_tags_and_head( | 173 | pub fn push_tags_and_head(tag_names: impl IntoIterator<Item = refs::FullName>, options: Options) -> anyhow::Result<()> { |
| 174 | tag_names: impl IntoIterator<Item = refs::mutable::FullName>, | ||
| 175 | options: Options, | ||
| 176 | ) -> anyhow::Result<()> { | ||
| 177 | if options.skip_push { | 174 | if options.skip_push { |
| 178 | return Ok(()); | 175 | return Ok(()); |
| 179 | } | 176 | } |
| @@ -32,7 +32,7 @@ fn main() -> anyhow::Result<()> { · 31 unmodified lines | |||
| 32 | let packed = repo.refs.packed_buffer()?; | 32 | let packed = repo.refs.packed_buffer()?; |
| 33 | let commit_id = repo | 33 | let commit_id = repo |
| 34 | .refs | 34 | .refs |
| 35 | .find_existing(&name, packed.as_ref())? | 35 | .find(&name, packed.as_ref())? |
| 36 | .peel_to_id_in_place(&repo.refs, packed.as_ref(), peel::none)? | 36 | .peel_to_id_in_place(&repo.refs, packed.as_ref(), peel::none)? |
| 37 | .to_owned(); | 37 | .to_owned(); |
| 38 | let db = &repo.odb; | 38 | let db = &repo.odb; |
| @@ -28,7 +28,7 @@ fn main() -> anyhow::Result<()> { · 27 unmodified lines | |||
| 28 | let packed = repo.refs.packed_buffer()?; | 28 | let packed = repo.refs.packed_buffer()?; |
| 29 | let commit_id = repo | 29 | let commit_id = repo |
| 30 | .refs | 30 | .refs |
| 31 | .find_existing(&name, packed.as_ref())? | 31 | .find(&name, packed.as_ref())? |
| 32 | .peel_to_id_in_place(&repo.refs, packed.as_ref(), peel::none)? | 32 | .peel_to_id_in_place(&repo.refs, packed.as_ref(), peel::none)? |
| 33 | .to_owned(); | 33 | .to_owned(); |
| 34 | (repo, commit_id) | 34 | (repo, commit_id) |
| @@ -1,6 +1,6 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | name = "git-actor" | 2 | name = "git-actor" |
| 3 | version = "0.4.0" | 3 | version = "0.5.0" |
| 4 | description = "A way to identify git actors" | 4 | description = "A way to identify git actors" |
| 5 | authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"] | 5 | authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"] |
| 6 | repository = "https://github.com/Byron/gitoxide" | 6 | repository = "https://github.com/Byron/gitoxide" |
| @@ -5,8 +5,6 @@ use bstr::{BStr, BString}; · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | /// | 6 | /// |
| 7 | pub mod signature; | 7 | pub mod signature; |
| 8 | /// | ||
| 9 | pub mod signature_ref; | ||
| 10 | 8 | ||
| 11 | const SPACE: &[u8; 1] = b" "; | 9 | const SPACE: &[u8; 1] = b" "; |
| 12 | 10 | ||
| @@ -68,13 +68,10 @@ mod tests { · 67 unmodified lines | |||
| 68 | use git_testtools::to_bstr_err; | 68 | use git_testtools::to_bstr_err; |
| 69 | use nom::IResult; | 69 | use nom::IResult; |
| 70 | 70 | ||
| 71 | use crate::{ | 71 | use crate::{signature, Sign, SignatureRef, Time}; |
| 72 | signature_ref::{self, SignatureRef}, | ||
| 73 | Sign, Time, | ||
| 74 | }; | ||
| 75 | 72 | ||
| 76 | fn decode(i: &[u8]) -> IResult<&[u8], SignatureRef<'_>, nom::error::VerboseError<&[u8]>> { | 73 | fn decode(i: &[u8]) -> IResult<&[u8], SignatureRef<'_>, nom::error::VerboseError<&[u8]>> { |
| 77 | signature_ref::decode(i) | 74 | signature::decode(i) |
| 78 | } | 75 | } |
| 79 | 76 | ||
| 80 | fn signature( | 77 | fn signature( |
| @@ -1,3 +1,16 @@ | |||
| 1 | mod _ref { | ||
| 2 | use crate::{signature::decode, SignatureRef}; | ||
| 3 | |||
| 4 | impl<'a> SignatureRef<'a> { | ||
| 5 | /// Deserialize a signature from the given `data`. | ||
| 6 | pub fn from_bytes<E: nom::error::ParseError<&'a [u8]> + nom::error::ContextError<&'a [u8]>>( | ||
| 7 | data: &'a [u8], | ||
| 8 | ) -> Result<SignatureRef<'a>, nom::Err<E>> { | ||
| 9 | decode(data).map(|(_, t)| t) | ||
| 10 | } | ||
| 11 | } | ||
| 12 | } | ||
| 13 | |||
| 1 | mod convert { | 14 | mod convert { |
| 2 | use crate::{Sign, Signature, SignatureRef, Time}; | 15 | use crate::{Sign, Signature, SignatureRef, Time}; |
| 3 | 16 | ||
| @@ -85,3 +98,7 @@ mod write { · 81 unmodified lines | |||
| 85 | Ok(name) | 98 | Ok(name) |
| 86 | } | 99 | } |
| 87 | } | 100 | } |
| 101 | |||
| 102 | /// | ||
| 103 | mod decode; | ||
| 104 | pub use decode::decode; | ||
| @@ -1,14 +0,0 @@ | |||
| 1 | use crate::SignatureRef; | ||
| 2 | |||
| 3 | impl<'a> SignatureRef<'a> { | ||
| 4 | /// Deserialize a signature from the given `data`. | ||
| 5 | pub fn from_bytes<E: nom::error::ParseError<&'a [u8]> + nom::error::ContextError<&'a [u8]>>( | ||
| 6 | data: &'a [u8], | ||
| 7 | ) -> Result<SignatureRef<'a>, nom::Err<E>> { | ||
| 8 | decode(data).map(|(_, t)| t) | ||
| 9 | } | ||
| 10 | } | ||
| 11 | |||
| 12 | /// | ||
| 13 | mod decode; | ||
| 14 | pub use decode::decode; | ||
| @@ -21,7 +21,7 @@ all-features = true · 20 unmodified lines | |||
| 21 | [dependencies] | 21 | [dependencies] |
| 22 | git-hash = { version = "^0.5.0", path = "../git-hash" } | 22 | git-hash = { version = "^0.5.0", path = "../git-hash" } |
| 23 | git-validate = { version = "^0.5.0", path = "../git-validate" } | 23 | git-validate = { version = "^0.5.0", path = "../git-validate" } |
| 24 | git-actor = { version ="^0.4.0", path = "../git-actor" } | 24 | git-actor = { version ="^0.5.0", path = "../git-actor" } |
| 25 | 25 | ||
| 26 | quick-error = "2.0.0" | 26 | quick-error = "2.0.0" |
| 27 | hex = "0.4.2" | 27 | hex = "0.4.2" |
| @@ -77,5 +77,5 @@ pub fn hex_hash<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], & · 76 unmodified lines | |||
| 77 | pub(crate) fn signature<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>( | 77 | pub(crate) fn signature<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>( |
| 78 | i: &'a [u8], | 78 | i: &'a [u8], |
| 79 | ) -> IResult<&'a [u8], git_actor::SignatureRef<'a>, E> { | 79 | ) -> IResult<&'a [u8], git_actor::SignatureRef<'a>, E> { |
| 80 | git_actor::signature_ref::decode(i) | 80 | git_actor::signature::decode(i) |
| 81 | } | 81 | } |
| @@ -56,7 +56,7 @@ impl fmt::Display for Kind { · 55 unmodified lines | |||
| 56 | pub mod tree { | 56 | pub mod tree { |
| 57 | /// The mode of items storable in a tree, similar to the file mode on a unix file system. | 57 | /// The mode of items storable in a tree, similar to the file mode on a unix file system. |
| 58 | /// | 58 | /// |
| 59 | /// Used in [mutable::Entry][crate::mutable::tree::Entry] and [signature_ref::Entry][crate::immutable::tree::Entry]. | 59 | /// Used in [mutable::Entry][crate::mutable::tree::Entry] and [tree::Entry][crate::immutable::tree::Entry]. |
| 60 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Ord, PartialOrd, Hash)] | 60 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Ord, PartialOrd, Hash)] |
| 61 | #[repr(u16)] | 61 | #[repr(u16)] |
| 62 | #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] | 62 | #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] |
| @@ -28,7 +28,7 @@ git-features = { version = "^0.16.0", path = "../git-features", features = ["wal · 27 unmodified lines | |||
| 28 | git-hash = { version = "^0.5.0", path = "../git-hash" } | 28 | git-hash = { version = "^0.5.0", path = "../git-hash" } |
| 29 | git-object = { version ="0.12.0", path = "../git-object" } | 29 | git-object = { version ="0.12.0", path = "../git-object" } |
| 30 | git-validate = { version = "^0.5.0", path = "../git-validate" } | 30 | git-validate = { version = "^0.5.0", path = "../git-validate" } |
| 31 | git-actor = { version ="^0.4.0", path = "../git-actor" } | 31 | git-actor = { version ="^0.5.0", path = "../git-actor" } |
| 32 | git-lock = { version ="^1.0.0", path = "../git-lock" } | 32 | git-lock = { version ="^1.0.0", path = "../git-lock" } |
| 33 | git-tempfile = { version ="^1.0.0", path = "../git-tempfile" } | 33 | git-tempfile = { version ="^1.0.0", path = "../git-tempfile" } |
| 34 | 34 | ||
| @@ -0,0 +1,71 @@ | |||
| 1 | use std::{borrow::Cow, convert::TryFrom, path::Path}; | ||
| 2 | |||
| 3 | use bstr::{BStr, BString, ByteSlice}; | ||
| 4 | |||
| 5 | use crate::FullName; | ||
| 6 | |||
| 7 | impl TryFrom<&str> for FullName { | ||
| 8 | type Error = git_validate::refname::Error; | ||
| 9 | |||
| 10 | fn try_from(value: &str) -> Result<Self, Self::Error> { | ||
| 11 | Ok(FullName(git_validate::refname(value.as_bytes().as_bstr())?.into())) | ||
| 12 | } | ||
| 13 | } | ||
| 14 | |||
| 15 | impl TryFrom<String> for FullName { | ||
| 16 | type Error = git_validate::refname::Error; | ||
| 17 | |||
| 18 | fn try_from(value: String) -> Result<Self, Self::Error> { | ||
| 19 | git_validate::refname(value.as_bytes().as_bstr())?; | ||
| 20 | Ok(FullName(value.into())) | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 24 | impl TryFrom<&BStr> for FullName { | ||
| 25 | type Error = git_validate::refname::Error; | ||
| 26 | |||
| 27 | fn try_from(value: &BStr) -> Result<Self, Self::Error> { | ||
| 28 | Ok(FullName(git_validate::refname(value)?.into())) | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | impl TryFrom<BString> for FullName { | ||
| 33 | type Error = git_validate::refname::Error; | ||
| 34 | |||
| 35 | fn try_from(value: BString) -> Result<Self, Self::Error> { | ||
| 36 | git_validate::refname(value.as_ref())?; | ||
| 37 | Ok(FullName(value)) | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | impl<'a> From<crate::FullNameRef<'a>> for FullName { | ||
| 42 | fn from(value: crate::FullNameRef<'a>) -> Self { | ||
| 43 | FullName(value.as_bstr().into()) | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | impl FullName { | ||
| 48 | /// Interpret this fully qualified reference name as partial name. | ||
| 49 | pub fn to_partial(&self) -> crate::PartialNameRef<'_> { | ||
| 50 | crate::PartialNameRef(self.0.as_bstr()) | ||
| 51 | } | ||
| 52 | |||
| 53 | /// Interpret this fully qualified reference as shared full name | ||
| 54 | pub fn to_ref(&self) -> crate::FullNameRef<'_> { | ||
| 55 | crate::FullNameRef(self.0.as_bstr()) | ||
| 56 | } | ||
| 57 | |||
| 58 | /// Convert this name into the relative path, lossily, identifying the reference location relative to a repository | ||
| 59 | pub fn to_path(&self) -> Cow<'_, Path> { | ||
| 60 | self.0.to_path().expect("UTF-8 conversion always succeeds").into() | ||
| 61 | } | ||
| 62 | |||
| 63 | /// Dissolve this instance and return the buffer. | ||
| 64 | pub fn into_inner(self) -> BString { | ||
| 65 | self.0 | ||
| 66 | } | ||
| 67 | /// Return ourselves as byte string which is a valid refname | ||
| 68 | pub fn as_bstr(&self) -> &BStr { | ||
| 69 | self.0.as_bstr() | ||
| 70 | } | ||
| 71 | } | ||
| @@ -19,12 +19,12 @@ · 18 unmodified lines | |||
| 19 | #![forbid(unsafe_code)] | 19 | #![forbid(unsafe_code)] |
| 20 | #![deny(missing_docs, rust_2018_idioms)] | 20 | #![deny(missing_docs, rust_2018_idioms)] |
| 21 | use bstr::{BStr, BString}; | 21 | use bstr::{BStr, BString}; |
| 22 | use git_hash::oid; | 22 | use git_hash::{oid, ObjectId}; |
| 23 | 23 | ||
| 24 | mod store; | 24 | mod store; |
| 25 | pub use store::{file, packed}; | 25 | pub use store::{file, packed}; |
| 26 | /// | 26 | |
| 27 | pub mod mutable; | 27 | mod fullname; |
| 28 | /// | 28 | /// |
| 29 | pub mod name; | 29 | pub mod name; |
| 30 | /// | 30 | /// |
| @@ -32,12 +32,17 @@ pub mod namespace; · 1 unmodified line | |||
| 32 | /// | 32 | /// |
| 33 | pub mod transaction; | 33 | pub mod transaction; |
| 34 | 34 | ||
| 35 | /// Indicate that the given BString is a validate reference name or path that can be used as path on disk or written as target | ||
| 36 | /// of a symbolic reference | ||
| 37 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] | ||
| 38 | pub struct FullName(pub(crate) BString); | ||
| 39 | |||
| 35 | /// A validated and potentially partial reference name - it can safely be used for common operations. | 40 | /// A validated and potentially partial reference name - it can safely be used for common operations. |
| 36 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] | 41 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] |
| 37 | pub struct FullName<'a>(&'a BStr); | 42 | pub struct FullNameRef<'a>(&'a BStr); |
| 38 | /// A validated complete and fully qualified reference name, safe to use for all operations. | 43 | /// A validated complete and fully qualified reference name, safe to use for all operations. |
| 39 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] | 44 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] |
| 40 | pub struct PartialName<'a>(&'a BStr); | 45 | pub struct PartialNameRef<'a>(&'a BStr); |
| 41 | 46 | ||
| 42 | /// A validated prefix for references to act as a namespace. | 47 | /// A validated prefix for references to act as a namespace. |
| 43 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] | 48 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] |
| @@ -55,9 +60,20 @@ pub enum Kind { · 11 unmodified lines | |||
| 55 | Symbolic, | 60 | Symbolic, |
| 56 | } | 61 | } |
| 57 | 62 | ||
| 63 | /// Denotes a ref target, equivalent to [`Kind`], but with mutable data. | ||
| 64 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] | ||
| 65 | pub enum Target { | ||
| 66 | /// A ref that points to an object id | ||
| 67 | Peeled(ObjectId), | ||
| 68 | /// A ref that points to another reference by its validated name, adding a level of indirection. | ||
| 69 | /// | ||
| 70 | /// Note that this is an extension of gitoxide which will be helpful in logging all reference changes. | ||
| 71 | Symbolic(FullName), | ||
| 72 | } | ||
| 73 | |||
| 58 | /// Denotes a ref target, equivalent to [`Kind`], but with signature_ref data. | 74 | /// Denotes a ref target, equivalent to [`Kind`], but with signature_ref data. |
| 59 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] | 75 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] |
| 60 | pub enum Target<'a> { | 76 | pub enum TargetRef<'a> { |
| 61 | /// A ref that points to an object id | 77 | /// A ref that points to an object id |
| 62 | Peeled(&'a oid), | 78 | Peeled(&'a oid), |
| 63 | /// A ref that points to another reference by its validated name, adding a level of indirection. | 79 | /// A ref that points to another reference by its validated name, adding a level of indirection. |
| @@ -1,162 +0,0 @@ | |||
| 1 | use std::{borrow::Cow, convert::TryFrom, fmt, path::Path}; | ||
| 2 | |||
| 3 | use bstr::{BStr, BString, ByteSlice}; | ||
| 4 | use git_hash::{oid, ObjectId}; | ||
| 5 | |||
| 6 | use crate::Kind; | ||
| 7 | |||
| 8 | /// Indicate that the given BString is a validate reference name or path that can be used as path on disk or written as target | ||
| 9 | /// of a symbolic reference | ||
| 10 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] | ||
| 11 | pub struct FullName(pub(crate) BString); | ||
| 12 | |||
| 13 | impl TryFrom<&str> for FullName { | ||
| 14 | type Error = git_validate::refname::Error; | ||
| 15 | |||
| 16 | fn try_from(value: &str) -> Result<Self, Self::Error> { | ||
| 17 | Ok(FullName(git_validate::refname(value.as_bytes().as_bstr())?.into())) | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | impl TryFrom<String> for FullName { | ||
| 22 | type Error = git_validate::refname::Error; | ||
| 23 | |||
| 24 | fn try_from(value: String) -> Result<Self, Self::Error> { | ||
| 25 | git_validate::refname(value.as_bytes().as_bstr())?; | ||
| 26 | Ok(FullName(value.into())) | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | impl TryFrom<&BStr> for FullName { | ||
| 31 | type Error = git_validate::refname::Error; | ||
| 32 | |||
| 33 | fn try_from(value: &BStr) -> Result<Self, Self::Error> { | ||
| 34 | Ok(FullName(git_validate::refname(value)?.into())) | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | impl TryFrom<BString> for FullName { | ||
| 39 | type Error = git_validate::refname::Error; | ||
| 40 | |||
| 41 | fn try_from(value: BString) -> Result<Self, Self::Error> { | ||
| 42 | git_validate::refname(value.as_ref())?; | ||
| 43 | Ok(FullName(value)) | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | impl<'a> From<crate::FullName<'a>> for FullName { | ||
| 48 | fn from(value: crate::FullName<'a>) -> Self { | ||
| 49 | FullName(value.as_bstr().into()) | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | impl FullName { | ||
| 54 | /// Interpret this fully qualified reference name as partial name. | ||
| 55 | pub fn to_partial(&self) -> crate::PartialName<'_> { | ||
| 56 | crate::PartialName(self.0.as_bstr()) | ||
| 57 | } | ||
| 58 | |||
| 59 | /// Interpret this fully qualified reference as shared full name | ||
| 60 | pub fn borrow(&self) -> crate::FullName<'_> { | ||
| 61 | crate::FullName(self.0.as_bstr()) | ||
| 62 | } | ||
| 63 | |||
| 64 | /// Convert this name into the relative path, lossily, identifying the reference location relative to a repository | ||
| 65 | pub fn to_path(&self) -> Cow<'_, Path> { | ||
| 66 | self.0.to_path().expect("UTF-8 conversion always succeeds").into() | ||
| 67 | } | ||
| 68 | |||
| 69 | /// Dissolve this instance and return the buffer. | ||
| 70 | pub fn into_inner(self) -> BString { | ||
| 71 | self.0 | ||
| 72 | } | ||
| 73 | /// Return ourselves as byte string which is a valid refname | ||
| 74 | pub fn as_bstr(&self) -> &BStr { | ||
| 75 | self.0.as_bstr() | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | /// Denotes a ref target, equivalent to [`Kind`][super::Kind], but with mutable data. | ||
| 80 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] | ||
| 81 | pub enum Target { | ||
| 82 | /// A ref that points to an object id | ||
| 83 | Peeled(ObjectId), | ||
| 84 | /// A ref that points to another reference by its validated name, adding a level of indirection. | ||
| 85 | /// | ||
| 86 | /// Note that this is an extension of gitoxide which will be helpful in logging all reference changes. | ||
| 87 | Symbolic(FullName), | ||
| 88 | } | ||
| 89 | |||
| 90 | impl Target { | ||
| 91 | /// Returns the kind of the target the ref is pointing to. | ||
| 92 | pub fn kind(&self) -> Kind { | ||
| 93 | match self { | ||
| 94 | Target::Symbolic(_) => Kind::Symbolic, | ||
| 95 | Target::Peeled(_) => Kind::Peeled, | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | /// Return true if this is a peeled target with a null hash | ||
| 100 | pub fn is_null(&self) -> bool { | ||
| 101 | match self { | ||
| 102 | Target::Peeled(oid) => oid.is_null(), | ||
| 103 | Target::Symbolic(_) => false, | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | /// Interpret this owned Target as shared Target | ||
| 108 | pub fn borrow(&self) -> crate::Target<'_> { | ||
| 109 | match self { | ||
| 110 | Target::Peeled(oid) => crate::Target::Peeled(oid), | ||
| 111 | Target::Symbolic(name) => crate::Target::Symbolic(name.0.as_bstr()), | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | /// Interpret this target as object id which maybe `None` if it is symbolic. | ||
| 116 | pub fn as_id(&self) -> Option<&oid> { | ||
| 117 | match self { | ||
| 118 | Target::Symbolic(_) => None, | ||
| 119 | Target::Peeled(oid) => Some(oid), | ||
| 120 | } | ||
| 121 | } | ||
| 122 | /// Interpret this target as name of the reference it points to which maybe `None` if it an object id. | ||
| 123 | pub fn as_name(&self) -> Option<&BStr> { | ||
| 124 | match self { | ||
| 125 | Target::Symbolic(name) => Some(name.as_bstr()), | ||
| 126 | Target::Peeled(_) => None, | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | /// Create an instance that signals that a reference should exist if this value is used in a [`Change`][crate::transaction::Change]. | ||
| 131 | pub fn must_exist() -> Self { | ||
| 132 | Target::Peeled(ObjectId::null_sha1()) | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | impl<'a> From<crate::Target<'a>> for Target { | ||
| 137 | fn from(src: crate::Target<'a>) -> Self { | ||
| 138 | match src { | ||
| 139 | crate::Target::Peeled(oid) => Target::Peeled(oid.to_owned()), | ||
| 140 | crate::Target::Symbolic(name) => Target::Symbolic(FullName(name.to_owned())), | ||
| 141 | } | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | impl<'a> PartialEq<crate::Target<'a>> for Target { | ||
| 146 | fn eq(&self, other: &crate::Target<'a>) -> bool { | ||
| 147 | match (self, other) { | ||
| 148 | (Target::Peeled(lhs), crate::Target::Peeled(rhs)) => lhs == rhs, | ||
| 149 | (Target::Symbolic(lhs), crate::Target::Symbolic(rhs)) => lhs.as_bstr() == *rhs, | ||
| 150 | _ => false, | ||
| 151 | } | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | impl fmt::Display for Target { | ||
| 156 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| 157 | match self { | ||
| 158 | Target::Peeled(oid) => oid.fmt(f), | ||
| 159 | Target::Symbolic(name) => write!(f, "ref: {}", name.as_bstr()), | ||
| 160 | } | ||
| 161 | } | ||
| 162 | } | ||
| @@ -6,12 +6,12 @@ use std::{ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | use bstr::{BStr, ByteSlice}; | 7 | use bstr::{BStr, ByteSlice}; |
| 8 | 8 | ||
| 9 | use crate::{FullName, PartialName}; | 9 | use crate::{FullNameRef, PartialNameRef}; |
| 10 | 10 | ||
| 11 | /// The error used in the [`PartialName`][super::PartialName]::try_from(…) implementations. | 11 | /// The error used in the [`PartialNameRef`][super::PartialNameRef]::try_from(…) implementations. |
| 12 | pub type Error = git_validate::reference::name::Error; | 12 | pub type Error = git_validate::reference::name::Error; |
| 13 | 13 | ||
| 14 | impl<'a> FullName<'a> { | 14 | impl<'a> FullNameRef<'a> { |
| 15 | /// Convert this name into the relative path identifying the reference location. | 15 | /// Convert this name into the relative path identifying the reference location. |
| 16 | pub fn to_path(self) -> Cow<'a, Path> { | 16 | pub fn to_path(self) -> Cow<'a, Path> { |
| 17 | self.0.to_path().expect("UTF-8 conversion always succeeds").into() | 17 | self.0.to_path().expect("UTF-8 conversion always succeeds").into() |
| @@ -23,7 +23,7 @@ impl<'a> FullName<'a> { · 5 unmodified lines | |||
| 23 | } | 23 | } |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | impl<'a> PartialName<'a> { | 26 | impl<'a> PartialNameRef<'a> { |
| 27 | /// Convert this name into the relative path possibly identifying the reference location. | 27 | /// Convert this name into the relative path possibly identifying the reference location. |
| 28 | /// Note that it may be only a partial path though. | 28 | /// Note that it may be only a partial path though. |
| 29 | pub fn to_partial_path(self) -> Cow<'a, Path> { | 29 | pub fn to_partial_path(self) -> Cow<'a, Path> { |
| @@ -36,62 +36,62 @@ impl<'a> PartialName<'a> { · 6 unmodified lines | |||
| 36 | } | 36 | } |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | impl<'a> TryFrom<&'a BStr> for FullName<'a> { | 39 | impl<'a> TryFrom<&'a BStr> for FullNameRef<'a> { |
| 40 | type Error = Error; | 40 | type Error = Error; |
| 41 | 41 | ||
| 42 | fn try_from(v: &'a BStr) -> Result<Self, Self::Error> { | 42 | fn try_from(v: &'a BStr) -> Result<Self, Self::Error> { |
| 43 | Ok(FullName(git_validate::reference::name(v)?)) | 43 | Ok(FullNameRef(git_validate::reference::name(v)?)) |
| 44 | } | 44 | } |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | impl<'a> TryFrom<FullName<'a>> for PartialName<'a> { | 47 | impl<'a> TryFrom<FullNameRef<'a>> for PartialNameRef<'a> { |
| 48 | type Error = Infallible; | 48 | type Error = Infallible; |
| 49 | 49 | ||
| 50 | fn try_from(v: FullName<'a>) -> Result<Self, Self::Error> { | 50 | fn try_from(v: FullNameRef<'a>) -> Result<Self, Self::Error> { |
| 51 | Ok(PartialName(v.0)) | 51 | Ok(PartialNameRef(v.0)) |
| 52 | } | 52 | } |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | impl<'a> TryFrom<&'a BStr> for PartialName<'a> { | 55 | impl<'a> TryFrom<&'a BStr> for PartialNameRef<'a> { |
| 56 | type Error = Error; | 56 | type Error = Error; |
| 57 | 57 | ||
| 58 | fn try_from(v: &'a BStr) -> Result<Self, Self::Error> { | 58 | fn try_from(v: &'a BStr) -> Result<Self, Self::Error> { |
| 59 | Ok(PartialName(git_validate::reference::name_partial(v)?)) | 59 | Ok(PartialNameRef(git_validate::reference::name_partial(v)?)) |
| 60 | } | 60 | } |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | impl<'a> TryFrom<&'a str> for FullName<'a> { | 63 | impl<'a> TryFrom<&'a str> for FullNameRef<'a> { |
| 64 | type Error = Error; | 64 | type Error = Error; |
| 65 | 65 | ||
| 66 | fn try_from(v: &'a str) -> Result<Self, Self::Error> { | 66 | fn try_from(v: &'a str) -> Result<Self, Self::Error> { |
| 67 | let v = v.as_bytes().as_bstr(); | 67 | let v = v.as_bytes().as_bstr(); |
| 68 | Ok(FullName(git_validate::reference::name(v)?)) | 68 | Ok(FullNameRef(git_validate::reference::name(v)?)) |
| 69 | } | 69 | } |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | impl<'a> TryFrom<&'a str> for PartialName<'a> { | 72 | impl<'a> TryFrom<&'a str> for PartialNameRef<'a> { |
| 73 | type Error = Error; | 73 | type Error = Error; |
| 74 | 74 | ||
| 75 | fn try_from(v: &'a str) -> Result<Self, Self::Error> { | 75 | fn try_from(v: &'a str) -> Result<Self, Self::Error> { |
| 76 | let v = v.as_bytes().as_bstr(); | 76 | let v = v.as_bytes().as_bstr(); |
| 77 | Ok(PartialName(git_validate::reference::name_partial(v)?)) | 77 | Ok(PartialNameRef(git_validate::reference::name_partial(v)?)) |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | impl<'a> TryFrom<&'a String> for FullName<'a> { | 81 | impl<'a> TryFrom<&'a String> for FullNameRef<'a> { |
| 82 | type Error = Error; | 82 | type Error = Error; |
| 83 | 83 | ||
| 84 | fn try_from(v: &'a String) -> Result<Self, Self::Error> { | 84 | fn try_from(v: &'a String) -> Result<Self, Self::Error> { |
| 85 | let v = v.as_bytes().as_bstr(); | 85 | let v = v.as_bytes().as_bstr(); |
| 86 | Ok(FullName(git_validate::reference::name(v)?)) | 86 | Ok(FullNameRef(git_validate::reference::name(v)?)) |
| 87 | } | 87 | } |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | impl<'a> TryFrom<&'a String> for PartialName<'a> { | 90 | impl<'a> TryFrom<&'a String> for PartialNameRef<'a> { |
| 91 | type Error = Error; | 91 | type Error = Error; |
| 92 | 92 | ||
| 93 | fn try_from(v: &'a String) -> Result<Self, Self::Error> { | 93 | fn try_from(v: &'a String) -> Result<Self, Self::Error> { |
| 94 | let v = v.as_bytes().as_bstr(); | 94 | let v = v.as_bytes().as_bstr(); |
| 95 | Ok(PartialName(git_validate::reference::name_partial(v)?)) | 95 | Ok(PartialNameRef(git_validate::reference::name_partial(v)?)) |
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| @@ -2,7 +2,7 @@ use std::{borrow::Cow, convert::TryInto, path::Path}; · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | use bstr::{BStr, BString, ByteSlice, ByteVec}; | 3 | use bstr::{BStr, BString, ByteSlice, ByteVec}; |
| 4 | 4 | ||
| 5 | use crate::{Namespace, PartialName}; | 5 | use crate::{Namespace, PartialNameRef}; |
| 6 | 6 | ||
| 7 | impl Namespace { | 7 | impl Namespace { |
| 8 | /// Dissolve ourselves into the interior representation | 8 | /// Dissolve ourselves into the interior representation |
| @@ -24,7 +24,7 @@ impl Namespace { · 15 unmodified lines | |||
| 24 | /// For more information, consult the [git namespace documentation](https://git-scm.com/docs/gitnamespaces). | 24 | /// For more information, consult the [git namespace documentation](https://git-scm.com/docs/gitnamespaces). |
| 25 | pub fn expand<'a, Name, E>(namespace: Name) -> Result<Namespace, git_validate::refname::Error> | 25 | pub fn expand<'a, Name, E>(namespace: Name) -> Result<Namespace, git_validate::refname::Error> |
| 26 | where | 26 | where |
| 27 | Name: TryInto<PartialName<'a>, Error = E>, | 27 | Name: TryInto<PartialNameRef<'a>, Error = E>, |
| 28 | git_validate::refname::Error: From<E>, | 28 | git_validate::refname::Error: From<E>, |
| 29 | { | 29 | { |
| 30 | let namespace = namespace.try_into()?.0; | 30 | let namespace = namespace.try_into()?.0; |
| @@ -9,12 +9,11 @@ pub use error::Error; · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | use crate::{ | 10 | use crate::{ |
| 11 | file, | 11 | file, |
| 12 | mutable::FullName, | ||
| 13 | store::{ | 12 | store::{ |
| 14 | file::{loose, path_to_name}, | 13 | file::{loose, path_to_name}, |
| 15 | packed, | 14 | packed, |
| 16 | }, | 15 | }, |
| 17 | PartialName, | 16 | FullName, PartialNameRef, |
| 18 | }; | 17 | }; |
| 19 | 18 | ||
| 20 | enum Transform { | 19 | enum Transform { |
| @@ -35,13 +34,13 @@ impl file::Store { · 14 unmodified lines | |||
| 35 | /// The lookup algorithm follows the one in [the git documentation][git-lookup-docs]. | 34 | /// The lookup algorithm follows the one in [the git documentation][git-lookup-docs]. |
| 36 | /// | 35 | /// |
| 37 | /// [git-lookup-docs]: https://github.com/git/git/blob/5d5b1473453400224ebb126bf3947e0a3276bdf5/Documentation/revisions.txt#L34-L46 | 36 | /// [git-lookup-docs]: https://github.com/git/git/blob/5d5b1473453400224ebb126bf3947e0a3276bdf5/Documentation/revisions.txt#L34-L46 |
| 38 | pub fn find<'a, 'p, 's, Name, E>( | 37 | pub fn try_find<'a, 'p, 's, Name, E>( |
| 39 | &'s self, | 38 | &'s self, |
| 40 | partial: Name, | 39 | partial: Name, |
| 41 | packed: Option<&'p packed::Buffer>, | 40 | packed: Option<&'p packed::Buffer>, |
| 42 | ) -> Result<Option<file::Reference<'p>>, Error> | 41 | ) -> Result<Option<file::Reference<'p>>, Error> |
| 43 | where | 42 | where |
| 44 | Name: TryInto<PartialName<'a>, Error = E>, | 43 | Name: TryInto<PartialNameRef<'a>, Error = E>, |
| 45 | Error: From<E>, | 44 | Error: From<E>, |
| 46 | { | 45 | { |
| 47 | let path = partial.try_into()?; | 46 | let path = partial.try_into()?; |
| @@ -49,12 +48,16 @@ impl file::Store { · 1 unmodified line | |||
| 49 | } | 48 | } |
| 50 | 49 | ||
| 51 | /// Similar to [`file::Store::find()`] but a non-existing ref is treated as error. | 50 | /// Similar to [`file::Store::find()`] but a non-existing ref is treated as error. |
| 52 | pub fn loose_find<'a, Name, E>(&self, partial: Name) -> Result<Option<loose::Reference>, Error> | 51 | /// |
| 52 | /// Find only loose references, that is references that aren't in the packed-refs buffer. | ||
| 53 | /// All symbolic references are loose references. | ||
| 54 | /// `HEAD` is always a loose reference. | ||
| 55 | pub fn try_find_loose<'a, Name, E>(&self, partial: Name) -> Result<Option<loose::Reference>, Error> | ||
| 53 | where | 56 | where |
| 54 | Name: TryInto<PartialName<'a>, Error = E>, | 57 | Name: TryInto<PartialNameRef<'a>, Error = E>, |
| 55 | Error: From<E>, | 58 | Error: From<E>, |
| 56 | { | 59 | { |
| 57 | self.find(partial, None) | 60 | self.try_find(partial, None) |
| 58 | .map(|r| r.map(|r| r.try_into().expect("only loose refs are found without pack"))) | 61 | .map(|r| r.map(|r| r.try_into().expect("only loose refs are found without pack"))) |
| 59 | } | 62 | } |
| 60 | 63 | ||
| @@ -116,8 +119,8 @@ impl file::Store { · 55 unmodified lines | |||
| 116 | if is_definitely_absolute { | 119 | if is_definitely_absolute { |
| 117 | if let Some(packed) = packed { | 120 | if let Some(packed) = packed { |
| 118 | let full_name = path_to_name(relative_path); | 121 | let full_name = path_to_name(relative_path); |
| 119 | let full_name = PartialName((*full_name).as_bstr()); | 122 | let full_name = PartialNameRef((*full_name).as_bstr()); |
| 120 | if let Some(packed_ref) = packed.find(full_name)? { | 123 | if let Some(packed_ref) = packed.try_find(full_name)? { |
| 121 | return Ok(Some(file::Reference::Packed(packed_ref))); | 124 | return Ok(Some(file::Reference::Packed(packed_ref))); |
| 122 | }; | 125 | }; |
| 123 | } | 126 | } |
| @@ -173,18 +176,18 @@ pub mod existing { · 49 unmodified lines | |||
| 173 | file::{find, loose}, | 176 | file::{find, loose}, |
| 174 | packed, | 177 | packed, |
| 175 | }, | 178 | }, |
| 176 | PartialName, | 179 | PartialNameRef, |
| 177 | }; | 180 | }; |
| 178 | 181 | ||
| 179 | impl file::Store { | 182 | impl file::Store { |
| 180 | /// Similar to [`file::Store::find_existing()`] but a non-existing ref is treated as error. | 183 | /// Similar to [`file::Store::find()`] but a non-existing ref is treated as error. |
| 181 | pub fn find_existing<'a, 'p, 's, Name, E>( | 184 | pub fn find<'a, 'p, 's, Name, E>( |
| 182 | &'s self, | 185 | &'s self, |
| 183 | partial: Name, | 186 | partial: Name, |
| 184 | packed: Option<&'p packed::Buffer>, | 187 | packed: Option<&'p packed::Buffer>, |
| 185 | ) -> Result<file::Reference<'p>, Error> | 188 | ) -> Result<file::Reference<'p>, Error> |
| 186 | where | 189 | where |
| 187 | Name: TryInto<PartialName<'a>, Error = E>, | 190 | Name: TryInto<PartialNameRef<'a>, Error = E>, |
| 188 | crate::name::Error: From<E>, | 191 | crate::name::Error: From<E>, |
| 189 | { | 192 | { |
| 190 | let path = partial | 193 | let path = partial |
| @@ -198,12 +201,12 @@ pub mod existing { · 7 unmodified lines | |||
| 198 | } | 201 | } |
| 199 | 202 | ||
| 200 | /// Similar to [`file::Store::find()`] won't handle packed-refs. | 203 | /// Similar to [`file::Store::find()`] won't handle packed-refs. |
| 201 | pub fn loose_find_existing<'a, Name, E>(&self, partial: Name) -> Result<loose::Reference, Error> | 204 | pub fn find_loose<'a, Name, E>(&self, partial: Name) -> Result<loose::Reference, Error> |
| 202 | where | 205 | where |
| 203 | Name: TryInto<PartialName<'a>, Error = E>, | 206 | Name: TryInto<PartialNameRef<'a>, Error = E>, |
| 204 | crate::name::Error: From<E>, | 207 | crate::name::Error: From<E>, |
| 205 | { | 208 | { |
| 206 | self.find_existing(partial, None) | 209 | self.find(partial, None) |
| 207 | .map(|r| r.try_into().expect("always loose without packed")) | 210 | .map(|r| r.try_into().expect("always loose without packed")) |
| 208 | } | 211 | } |
| 209 | } | 212 | } |
| @@ -1,5 +1,6 @@ | |||
| 1 | use bstr::ByteSlice; | 1 | use bstr::ByteSlice; |
| 2 | 2 | ||
| 3 | use crate::store::file; | ||
| 3 | use crate::store::file::{log, log::iter::decode::LineNumber}; | 4 | use crate::store::file::{log, log::iter::decode::LineNumber}; |
| 4 | 5 | ||
| 5 | /// | 6 | /// |
| @@ -51,9 +52,9 @@ pub mod decode { · 45 unmodified lines | |||
| 51 | /// This iterator is useful when the ref log file is going to be rewritten which forces processing of the entire file. | 52 | /// This iterator is useful when the ref log file is going to be rewritten which forces processing of the entire file. |
| 52 | /// It will continue parsing even if individual log entries failed to parse, leaving it to the driver to decide whether to | 53 | /// It will continue parsing even if individual log entries failed to parse, leaving it to the driver to decide whether to |
| 53 | /// abort or continue. | 54 | /// abort or continue. |
| 54 | pub fn forward(lines: &[u8]) -> impl Iterator<Item = Result<log::Line<'_>, decode::Error>> { | 55 | pub fn forward(lines: &[u8]) -> impl Iterator<Item = Result<log::LineRef<'_>, decode::Error>> { |
| 55 | lines.as_bstr().lines().enumerate().map(|(ln, line)| { | 56 | lines.as_bstr().lines().enumerate().map(|(ln, line)| { |
| 56 | log::Line::from_bytes(line).map_err(|err| decode::Error::new(err, decode::LineNumber::FromStart(ln))) | 57 | log::LineRef::from_bytes(line).map_err(|err| decode::Error::new(err, decode::LineNumber::FromStart(ln))) |
| 57 | }) | 58 | }) |
| 58 | } | 59 | } |
| 59 | 60 | ||
| @@ -93,7 +94,7 @@ impl<'a, F> Iterator for Reverse<'a, F> · 33 unmodified lines | |||
| 93 | where | 94 | where |
| 94 | F: std::io::Read + std::io::Seek, | 95 | F: std::io::Read + std::io::Seek, |
| 95 | { | 96 | { |
| 96 | type Item = std::io::Result<Result<log::mutable::Line, decode::Error>>; | 97 | type Item = std::io::Result<Result<file::log::Line, decode::Error>>; |
| 97 | 98 | ||
| 98 | fn next(&mut self) -> Option<Self::Item> { | 99 | fn next(&mut self) -> Option<Self::Item> { |
| 99 | match (self.last_nl_pos.take(), self.read_and_pos.take()) { | 100 | match (self.last_nl_pos.take(), self.read_and_pos.take()) { |
| @@ -124,7 +125,7 @@ where · 24 unmodified lines | |||
| 124 | self.read_and_pos = Some(read_and_pos); | 125 | self.read_and_pos = Some(read_and_pos); |
| 125 | self.last_nl_pos = Some(start); | 126 | self.last_nl_pos = Some(start); |
| 126 | let buf = &self.buf[start + 1..end]; | 127 | let buf = &self.buf[start + 1..end]; |
| 127 | let res = Some(Ok(log::Line::from_bytes(buf) | 128 | let res = Some(Ok(log::LineRef::from_bytes(buf) |
| 128 | .map_err(|err| decode::Error::new(err, LineNumber::FromEnd(self.count))) | 129 | .map_err(|err| decode::Error::new(err, LineNumber::FromEnd(self.count))) |
| 129 | .map(Into::into))); | 130 | .map(Into::into))); |
| 130 | self.count += 1; | 131 | self.count += 1; |
| @@ -134,7 +135,7 @@ where · 3 unmodified lines | |||
| 134 | let (mut read, last_read_pos) = read_and_pos; | 135 | let (mut read, last_read_pos) = read_and_pos; |
| 135 | if last_read_pos == 0 { | 136 | if last_read_pos == 0 { |
| 136 | let buf = &self.buf[..end]; | 137 | let buf = &self.buf[..end]; |
| 137 | Some(Ok(log::Line::from_bytes(buf) | 138 | Some(Ok(log::LineRef::from_bytes(buf) |
| 138 | .map_err(|err| decode::Error::new(err, LineNumber::FromEnd(self.count))) | 139 | .map_err(|err| decode::Error::new(err, LineNumber::FromEnd(self.count))) |
| 139 | .map(Into::into))) | 140 | .map(Into::into))) |
| 140 | } else { | 141 | } else { |
| @@ -1,8 +1,59 @@ | |||
| 1 | use git_hash::ObjectId; | 1 | use git_hash::ObjectId; |
| 2 | 2 | ||
| 3 | use crate::store::file::log::Line; | 3 | use crate::store::file::log::Line; |
| 4 | use crate::store::file::log::LineRef; | ||
| 4 | 5 | ||
| 5 | impl<'a> Line<'a> { | 6 | impl<'a> LineRef<'a> { |
| 7 | /// Convert this instance into its mutable counterpart | ||
| 8 | pub fn to_owned(&self) -> Line { | ||
| 9 | self.clone().into() | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | mod write { | ||
| 14 | use std::io; | ||
| 15 | |||
| 16 | use bstr::{BStr, ByteSlice}; | ||
| 17 | use quick_error::quick_error; | ||
| 18 | |||
| 19 | use crate::store::file::log::Line; | ||
| 20 | |||
| 21 | quick_error! { | ||
| 22 | /// The Error produced by [`Line::write_to()`] (but wrapped in an io error). | ||
| 23 | #[derive(Debug)] | ||
| 24 | #[allow(missing_docs)] | ||
| 25 | enum Error { | ||
| 26 | IllegalCharacter { | ||
| 27 | display("Messages must not contain newlines\\n") | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | impl From<Error> for io::Error { | ||
| 33 | fn from(err: Error) -> Self { | ||
| 34 | io::Error::new(io::ErrorKind::Other, err) | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | /// Output | ||
| 39 | impl Line { | ||
| 40 | /// Serialize this instance to `out` in the git serialization format for ref log lines. | ||
| 41 | pub fn write_to(&self, mut out: impl io::Write) -> io::Result<()> { | ||
| 42 | write!(out, "{} {} ", self.previous_oid, self.new_oid)?; | ||
| 43 | self.signature.write_to(&mut out)?; | ||
| 44 | writeln!(out, "\t{}", check_newlines(self.message.as_ref())?) | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | fn check_newlines(input: &BStr) -> Result<&BStr, Error> { | ||
| 49 | if input.find_byte(b'\n').is_some() { | ||
| 50 | return Err(Error::IllegalCharacter); | ||
| 51 | } | ||
| 52 | Ok(input) | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | impl<'a> LineRef<'a> { | ||
| 6 | /// The previous object id of the ref. It will be a null hash if there was no previous id as | 57 | /// The previous object id of the ref. It will be a null hash if there was no previous id as |
| 7 | /// this ref is being created. | 58 | /// this ref is being created. |
| 8 | pub fn previous_oid(&self) -> ObjectId { | 59 | pub fn previous_oid(&self) -> ObjectId { |
| @@ -14,6 +65,17 @@ impl<'a> Line<'a> { · 5 unmodified lines | |||
| 14 | } | 65 | } |
| 15 | } | 66 | } |
| 16 | 67 | ||
| 68 | impl<'a> From<LineRef<'a>> for Line { | ||
| 69 | fn from(v: LineRef<'a>) -> Self { | ||
| 70 | Line { | ||
| 71 | previous_oid: v.previous_oid(), | ||
| 72 | new_oid: v.new_oid(), | ||
| 73 | signature: v.signature.into(), | ||
| 74 | message: v.message.into(), | ||
| 75 | } | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 17 | /// | 79 | /// |
| 18 | pub mod decode { | 80 | pub mod decode { |
| 19 | use bstr::{BStr, ByteSlice}; | 81 | use bstr::{BStr, ByteSlice}; |
| @@ -25,7 +87,7 @@ pub mod decode { · 5 unmodified lines | |||
| 25 | IResult, | 87 | IResult, |
| 26 | }; | 88 | }; |
| 27 | 89 | ||
| 28 | use crate::{file::log::Line, parse::hex_hash}; | 90 | use crate::{file::log::LineRef, parse::hex_hash}; |
| 29 | 91 | ||
| 30 | /// | 92 | /// |
| 31 | mod error { | 93 | mod error { |
| @@ -59,9 +121,9 @@ pub mod decode { · 27 unmodified lines | |||
| 59 | } | 121 | } |
| 60 | pub use error::Error; | 122 | pub use error::Error; |
| 61 | 123 | ||
| 62 | impl<'a> Line<'a> { | 124 | impl<'a> LineRef<'a> { |
| 63 | /// Decode a line from the given bytes which are expected to start at a hex sha. | 125 | /// Decode a line from the given bytes which are expected to start at a hex sha. |
| 64 | pub fn from_bytes(input: &'a [u8]) -> Result<Line<'a>, Error> { | 126 | pub fn from_bytes(input: &'a [u8]) -> Result<LineRef<'a>, Error> { |
| 65 | one::<()>(input).map(|(_, l)| l).map_err(|_| Error::new(input)) | 127 | one::<()>(input).map(|(_, l)| l).map_err(|_| Error::new(input)) |
| 66 | } | 128 | } |
| 67 | } | 129 | } |
| @@ -74,13 +136,13 @@ pub mod decode { · 6 unmodified lines | |||
| 74 | } | 136 | } |
| 75 | } | 137 | } |
| 76 | 138 | ||
| 77 | fn one<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(bytes: &'a [u8]) -> IResult<&[u8], Line<'a>, E> { | 139 | fn one<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(bytes: &'a [u8]) -> IResult<&[u8], LineRef<'a>, E> { |
| 78 | let (i, (old, new, signature, message_sep, message)) = context( | 140 | let (i, (old, new, signature, message_sep, message)) = context( |
| 79 | "<old-hexsha> <new-hexsha> <name> <<email>> <timestamp> <tz>\\t<message>", | 141 | "<old-hexsha> <new-hexsha> <name> <<email>> <timestamp> <tz>\\t<message>", |
| 80 | tuple(( | 142 | tuple(( |
| 81 | context("<old-hexsha>", terminated(hex_hash, tag(b" "))), | 143 | context("<old-hexsha>", terminated(hex_hash, tag(b" "))), |
| 82 | context("<new-hexsha>", terminated(hex_hash, tag(b" "))), | 144 | context("<new-hexsha>", terminated(hex_hash, tag(b" "))), |
| 83 | context("<name> <<email>> <timestamp>", git_actor::signature_ref::decode), | 145 | context("<name> <<email>> <timestamp>", git_actor::signature::decode), |
| 84 | opt(tag(b"\t")), | 146 | opt(tag(b"\t")), |
| 85 | context("<optional message>", message), | 147 | context("<optional message>", message), |
| 86 | )), | 148 | )), |
| @@ -100,7 +162,7 @@ pub mod decode { · 13 unmodified lines | |||
| 100 | 162 | ||
| 101 | Ok(( | 163 | Ok(( |
| 102 | i, | 164 | i, |
| 103 | Line { | 165 | LineRef { |
| 104 | previous_oid: old, | 166 | previous_oid: old, |
| 105 | new_oid: new, | 167 | new_oid: new, |
| 106 | signature, | 168 | signature, |
| @@ -161,7 +223,7 @@ pub mod decode { · 54 unmodified lines | |||
| 161 | for input in &[line_without_nl, line_with_nl] { | 223 | for input in &[line_without_nl, line_with_nl] { |
| 162 | assert_eq!( | 224 | assert_eq!( |
| 163 | one::<nom::error::Error<_>>(input).expect("successful parsing").1, | 225 | one::<nom::error::Error<_>>(input).expect("successful parsing").1, |
| 164 | Line { | 226 | LineRef { |
| 165 | previous_oid: NULL_SHA1.as_bstr(), | 227 | previous_oid: NULL_SHA1.as_bstr(), |
| 166 | new_oid: NULL_SHA1.as_bstr(), | 228 | new_oid: NULL_SHA1.as_bstr(), |
| 167 | signature: git_actor::SignatureRef { | 229 | signature: git_actor::SignatureRef { |
| @@ -187,7 +249,7 @@ pub mod decode { · 19 unmodified lines | |||
| 187 | for input in &[line_without_nl, line_with_nl] { | 249 | for input in &[line_without_nl, line_with_nl] { |
| 188 | let (remaining, res) = one::<nom::error::Error<_>>(input).expect("successful parsing"); | 250 | let (remaining, res) = one::<nom::error::Error<_>>(input).expect("successful parsing"); |
| 189 | assert!(remaining.is_empty(), "all consuming even without trailing newline"); | 251 | assert!(remaining.is_empty(), "all consuming even without trailing newline"); |
| 190 | let actual = Line { | 252 | let actual = LineRef { |
| 191 | previous_oid: b"a5828ae6b52137b913b978e16cd2334482eb4c1f".as_bstr(), | 253 | previous_oid: b"a5828ae6b52137b913b978e16cd2334482eb4c1f".as_bstr(), |
| 192 | new_oid: b"89b43f80a514aee58b662ad606e6352e03eaeee4".as_bstr(), | 254 | new_oid: b"89b43f80a514aee58b662ad606e6352e03eaeee4".as_bstr(), |
| 193 | signature: git_actor::SignatureRef { | 255 | signature: git_actor::SignatureRef { |
| @@ -1,15 +1,22 @@ | |||
| 1 | use bstr::BStr; | 1 | use bstr::BStr; |
| 2 | 2 | ||
| 3 | use git_hash::ObjectId; | ||
| 4 | use git_object::bstr::BString; | ||
| 5 | |||
| 3 | pub use super::loose::reflog::{create_or_update, Error}; | 6 | pub use super::loose::reflog::{create_or_update, Error}; |
| 4 | 7 | ||
| 8 | /// | ||
| 9 | pub mod iter; | ||
| 10 | mod line; | ||
| 11 | |||
| 5 | /// A parsed ref log line. | 12 | /// A parsed ref log line. |
| 6 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] | 13 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] |
| 7 | #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] | 14 | #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] |
| 8 | #[non_exhaustive] | 15 | #[non_exhaustive] |
| 9 | pub struct Line<'a> { | 16 | pub struct LineRef<'a> { |
| 10 | /// The previous object id in hexadecimal. Use [`Line::previous_oid()`] to get a more usable form. | 17 | /// The previous object id in hexadecimal. Use [`LineRef::previous_oid()`] to get a more usable form. |
| 11 | pub previous_oid: &'a BStr, | 18 | pub previous_oid: &'a BStr, |
| 12 | /// The new object id in hexadecimal. Use [`Line::new_oid()`] to get a more usable form. | 19 | /// The new object id in hexadecimal. Use [`LineRef::new_oid()`] to get a more usable form. |
| 13 | pub new_oid: &'a BStr, | 20 | pub new_oid: &'a BStr, |
| 14 | /// The signature of the currently configured committer. | 21 | /// The signature of the currently configured committer. |
| 15 | #[cfg_attr(feature = "serde1", serde(borrow))] | 22 | #[cfg_attr(feature = "serde1", serde(borrow))] |
| @@ -18,87 +25,16 @@ pub struct Line<'a> { · 2 unmodified lines | |||
| 18 | pub message: &'a BStr, | 25 | pub message: &'a BStr, |
| 19 | } | 26 | } |
| 20 | 27 | ||
| 21 | /// | 28 | /// A parsed ref log line that can be changed |
| 22 | pub mod mutable { | 29 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] |
| 23 | use bstr::BString; | 30 | #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] |
| 24 | use git_hash::ObjectId; | 31 | pub struct Line { |
| 25 | 32 | /// The previous object id. Can be a null-sha to indicate this is a line for a new ref. | |
| 26 | /// A parsed ref log line that can be changed | 33 | pub previous_oid: ObjectId, |
| 27 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] | 34 | /// The new object id. Can be a null-sha to indicate this ref is being deleted. |
| 28 | #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] | 35 | pub new_oid: ObjectId, |
| 29 | pub struct Line { | 36 | /// The signature of the currently configured committer. |
| 30 | /// The previous object id. Can be a null-sha to indicate this is a line for a new ref. | 37 | pub signature: git_actor::Signature, |
| 31 | pub previous_oid: ObjectId, | 38 | /// The message providing details about the operation performed in this log line. |
| 32 | /// The new object id. Can be a null-sha to indicate this ref is being deleted. | 39 | pub message: BString, |
| 33 | pub new_oid: ObjectId, | ||
| 34 | /// The signature of the currently configured committer. | ||
| 35 | pub signature: git_actor::Signature, | ||
| 36 | /// The message providing details about the operation performed in this log line. | ||
| 37 | pub message: BString, | ||
| 38 | } | ||
| 39 | |||
| 40 | impl<'a> From<super::Line<'a>> for Line { | ||
| 41 | fn from(v: super::Line<'a>) -> Self { | ||
| 42 | Line { | ||
| 43 | previous_oid: v.previous_oid(), | ||
| 44 | new_oid: v.new_oid(), | ||
| 45 | signature: v.signature.into(), | ||
| 46 | message: v.message.into(), | ||
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | impl<'a> super::Line<'a> { | ||
| 52 | /// Convert this instance into its mutable counterpart | ||
| 53 | pub fn to_mutable(&self) -> Line { | ||
| 54 | self.clone().into() | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | mod write { | ||
| 59 | use std::io; | ||
| 60 | |||
| 61 | use bstr::{BStr, ByteSlice}; | ||
| 62 | use quick_error::quick_error; | ||
| 63 | |||
| 64 | use super::Line; | ||
| 65 | |||
| 66 | quick_error! { | ||
| 67 | /// The Error produced by [`Line::write_to()`] (but wrapped in an io error). | ||
| 68 | #[derive(Debug)] | ||
| 69 | #[allow(missing_docs)] | ||
| 70 | enum Error { | ||
| 71 | IllegalCharacter { | ||
| 72 | display("Messages must not contain newlines\\n") | ||
| 73 | } | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | impl From<Error> for io::Error { | ||
| 78 | fn from(err: Error) -> Self { | ||
| 79 | io::Error::new(io::ErrorKind::Other, err) | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | /// Output | ||
| 84 | impl Line { | ||
| 85 | /// Serialize this instance to `out` in the git serialization format for ref log lines. | ||
| 86 | pub fn write_to(&self, mut out: impl io::Write) -> io::Result<()> { | ||
| 87 | write!(out, "{} {} ", self.previous_oid, self.new_oid)?; | ||
| 88 | self.signature.write_to(&mut out)?; | ||
| 89 | writeln!(out, "\t{}", check_newlines(self.message.as_ref())?) | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | fn check_newlines(input: &BStr) -> Result<&BStr, Error> { | ||
| 94 | if input.find_byte(b'\n').is_some() { | ||
| 95 | return Err(Error::IllegalCharacter); | ||
| 96 | } | ||
| 97 | Ok(input) | ||
| 98 | } | ||
| 99 | } | ||
| 100 | } | 40 | } |
| 101 | |||
| 102 | /// | ||
| 103 | pub mod iter; | ||
| 104 | mod line; | ||
| @@ -8,8 +8,8 @@ use git_features::fs::walkdir::DirEntryIter; · 7 unmodified lines | |||
| 8 | use os_str_bytes::OsStrBytes; | 8 | use os_str_bytes::OsStrBytes; |
| 9 | 9 | ||
| 10 | use crate::{ | 10 | use crate::{ |
| 11 | mutable::FullName, | ||
| 12 | store::file::{self, loose::Reference}, | 11 | store::file::{self, loose::Reference}, |
| 12 | FullName, | ||
| 13 | }; | 13 | }; |
| 14 | 14 | ||
| 15 | /// An iterator over all valid loose reference paths as seen from a particular base directory. | 15 | /// An iterator over all valid loose reference paths as seen from a particular base directory. |
| @@ -1,12 +1,12 @@ | |||
| 1 | use crate::{mutable, Kind}; | 1 | use crate::{FullName, Kind, Target}; |
| 2 | 2 | ||
| 3 | /// A git _ref_ which is stored in a file. | 3 | /// A git _ref_ which is stored in a file. |
| 4 | #[derive(Debug, PartialOrd, PartialEq, Ord, Eq, Hash, Clone)] | 4 | #[derive(Debug, PartialOrd, PartialEq, Ord, Eq, Hash, Clone)] |
| 5 | pub struct Reference { | 5 | pub struct Reference { |
| 6 | /// The path to uniquely identify this ref within its store. | 6 | /// The path to uniquely identify this ref within its store. |
| 7 | pub name: mutable::FullName, | 7 | pub name: FullName, |
| 8 | /// The target of the reference, either a symbolic reference by full name or an object by its id. | 8 | /// The target of the reference, either a symbolic reference by full name or an object by its id. |
| 9 | pub target: mutable::Target, | 9 | pub target: Target, |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | impl Reference { | 12 | impl Reference { |
| @@ -11,9 +11,9 @@ use nom::{ · 10 unmodified lines | |||
| 11 | use quick_error::quick_error; | 11 | use quick_error::quick_error; |
| 12 | 12 | ||
| 13 | use crate::{ | 13 | use crate::{ |
| 14 | mutable, | ||
| 15 | parse::{hex_hash, newline}, | 14 | parse::{hex_hash, newline}, |
| 16 | store::file::loose::Reference, | 15 | store::file::loose::Reference, |
| 16 | FullName, Target, | ||
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | enum MaybeUnsafeState { | 19 | enum MaybeUnsafeState { |
| @@ -36,18 +36,16 @@ quick_error! { · 16 unmodified lines | |||
| 36 | } | 36 | } |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | impl TryFrom<MaybeUnsafeState> for mutable::Target { | 39 | impl TryFrom<MaybeUnsafeState> for Target { |
| 40 | type Error = Error; | 40 | type Error = Error; |
| 41 | 41 | ||
| 42 | fn try_from(v: MaybeUnsafeState) -> Result<Self, Self::Error> { | 42 | fn try_from(v: MaybeUnsafeState) -> Result<Self, Self::Error> { |
| 43 | Ok(match v { | 43 | Ok(match v { |
| 44 | MaybeUnsafeState::Id(id) => mutable::Target::Peeled(id), | 44 | MaybeUnsafeState::Id(id) => Target::Peeled(id), |
| 45 | MaybeUnsafeState::UnvalidatedPath(name) => { | 45 | MaybeUnsafeState::UnvalidatedPath(name) => Target::Symbolic(match git_validate::refname(name.as_ref()) { |
| 46 | mutable::Target::Symbolic(match git_validate::refname(name.as_ref()) { | 46 | Ok(_) => FullName(name), |
| 47 | Ok(_) => mutable::FullName(name), | 47 | Err(err) => return Err(Error::RefnameValidation { err, path: name }), |
| 48 | Err(err) => return Err(Error::RefnameValidation { err, path: name }), | 48 | }), |
| 49 | }) | ||
| 50 | } | ||
| 51 | }) | 49 | }) |
| 52 | } | 50 | } |
| 53 | } | 51 | } |
| @@ -55,7 +53,7 @@ impl TryFrom<MaybeUnsafeState> for mutable::Target { · 1 unmodified line | |||
| 55 | impl Reference { | 53 | impl Reference { |
| 56 | /// Create a new reference of the given `parent` store with `relative_path` service as unique identifier | 54 | /// Create a new reference of the given `parent` store with `relative_path` service as unique identifier |
| 57 | /// at which the `path_contents` was read to obtain the refs value. | 55 | /// at which the `path_contents` was read to obtain the refs value. |
| 58 | pub fn try_from_path(name: mutable::FullName, path_contents: &[u8]) -> Result<Self, Error> { | 56 | pub fn try_from_path(name: FullName, path_contents: &[u8]) -> Result<Self, Error> { |
| 59 | Ok(Reference { | 57 | Ok(Reference { |
| 60 | name, | 58 | name, |
| 61 | target: parse(path_contents) | 59 | target: parse(path_contents) |
| @@ -18,7 +18,7 @@ impl Reference { · 17 unmodified lines | |||
| 18 | /// If the caller needs to know if it's readable, try to read the log instead with a reverse or forward iterator. | 18 | /// If the caller needs to know if it's readable, try to read the log instead with a reverse or forward iterator. |
| 19 | pub fn log_exists(&self, store: &file::Store) -> bool { | 19 | pub fn log_exists(&self, store: &file::Store) -> bool { |
| 20 | store | 20 | store |
| 21 | .reflog_exists(self.name.borrow()) | 21 | .reflog_exists(self.name.to_ref()) |
| 22 | .expect("name conversion infallible") | 22 | .expect("name conversion infallible") |
| 23 | } | 23 | } |
| 24 | /// Return a reflog reverse iterator for this ref, reading chunks from the back into the fixed buffer `buf`, in the given `store`. | 24 | /// Return a reflog reverse iterator for this ref, reading chunks from the back into the fixed buffer `buf`, in the given `store`. |
| @@ -30,7 +30,7 @@ impl Reference { · 5 unmodified lines | |||
| 30 | store: &file::Store, | 30 | store: &file::Store, |
| 31 | buf: &'b mut [u8], | 31 | buf: &'b mut [u8], |
| 32 | ) -> std::io::Result<Option<log::iter::Reverse<'b, std::fs::File>>> { | 32 | ) -> std::io::Result<Option<log::iter::Reverse<'b, std::fs::File>>> { |
| 33 | store.reflog_iter_rev(self.name.borrow(), buf).map_err(must_be_io_err) | 33 | store.reflog_iter_rev(self.name.to_ref(), buf).map_err(must_be_io_err) |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | /// Return a reflog forward iterator for this ref and write its file contents into `buf`, in the given `store`. | 36 | /// Return a reflog forward iterator for this ref and write its file contents into `buf`, in the given `store`. |
| @@ -41,7 +41,7 @@ impl Reference { · 4 unmodified lines | |||
| 41 | &'a self, | 41 | &'a self, |
| 42 | store: &file::Store, | 42 | store: &file::Store, |
| 43 | buf: &'b mut Vec<u8>, | 43 | buf: &'b mut Vec<u8>, |
| 44 | ) -> std::io::Result<Option<impl Iterator<Item = Result<log::Line<'b>, log::iter::decode::Error>> + 'a>> { | 44 | ) -> std::io::Result<Option<impl Iterator<Item = Result<log::LineRef<'b>, log::iter::decode::Error>> + 'a>> { |
| 45 | store.reflog_iter(self.name.borrow(), buf).map_err(must_be_io_err) | 45 | store.reflog_iter(self.name.to_ref(), buf).map_err(must_be_io_err) |
| 46 | } | 46 | } |
| 47 | } | 47 | } |
| @@ -2,11 +2,11 @@ use quick_error::quick_error; · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | use crate::{ | 3 | use crate::{ |
| 4 | file, | 4 | file, |
| 5 | mutable::Target, | ||
| 6 | store::{ | 5 | store::{ |
| 7 | file::{find, loose}, | 6 | file::{find, loose}, |
| 8 | packed, | 7 | packed, |
| 9 | }, | 8 | }, |
| 9 | Target, | ||
| 10 | }; | 10 | }; |
| 11 | 11 | ||
| 12 | quick_error! { | 12 | quick_error! { |
| @@ -67,8 +67,8 @@ pub mod to_id { · 54 unmodified lines | |||
| 67 | use quick_error::quick_error; | 67 | use quick_error::quick_error; |
| 68 | 68 | ||
| 69 | use crate::{ | 69 | use crate::{ |
| 70 | mutable::{FullName, Target}, | ||
| 71 | store::{file, file::loose, packed}, | 70 | store::{file, file::loose, packed}, |
| 71 | FullName, Target, | ||
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | quick_error! { | 74 | quick_error! { |
| @@ -2,7 +2,7 @@ use std::{convert::TryInto, io::Read, path::PathBuf}; · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | use crate::{ | 3 | use crate::{ |
| 4 | store::{file, file::log}, | 4 | store::{file, file::log}, |
| 5 | FullName, | 5 | FullNameRef, |
| 6 | }; | 6 | }; |
| 7 | 7 | ||
| 8 | impl file::Store { | 8 | impl file::Store { |
| @@ -13,7 +13,7 @@ impl file::Store { · 4 unmodified lines | |||
| 13 | /// If the caller needs to know if it's readable, try to read the log instead with a reverse or forward iterator. | 13 | /// If the caller needs to know if it's readable, try to read the log instead with a reverse or forward iterator. |
| 14 | pub fn reflog_exists<'a, Name, E>(&self, name: Name) -> Result<bool, E> | 14 | pub fn reflog_exists<'a, Name, E>(&self, name: Name) -> Result<bool, E> |
| 15 | where | 15 | where |
| 16 | Name: TryInto<FullName<'a>, Error = E>, | 16 | Name: TryInto<FullNameRef<'a>, Error = E>, |
| 17 | crate::name::Error: From<E>, | 17 | crate::name::Error: From<E>, |
| 18 | { | 18 | { |
| 19 | Ok(self.reflog_path(name.try_into()?).is_file()) | 19 | Ok(self.reflog_path(name.try_into()?).is_file()) |
| @@ -29,10 +29,10 @@ impl file::Store { · 9 unmodified lines | |||
| 29 | buf: &'b mut [u8], | 29 | buf: &'b mut [u8], |
| 30 | ) -> Result<Option<log::iter::Reverse<'b, std::fs::File>>, Error> | 30 | ) -> Result<Option<log::iter::Reverse<'b, std::fs::File>>, Error> |
| 31 | where | 31 | where |
| 32 | Name: TryInto<FullName<'a>, Error = E>, | 32 | Name: TryInto<FullNameRef<'a>, Error = E>, |
| 33 | crate::name::Error: From<E>, | 33 | crate::name::Error: From<E>, |
| 34 | { | 34 | { |
| 35 | let name: FullName<'_> = name.try_into().map_err(|err| Error::RefnameValidation(err.into()))?; | 35 | let name: FullNameRef<'_> = name.try_into().map_err(|err| Error::RefnameValidation(err.into()))?; |
| 36 | let path = self.reflog_path(name); | 36 | let path = self.reflog_path(name); |
| 37 | if path.is_dir() { | 37 | if path.is_dir() { |
| 38 | return Ok(None); | 38 | return Ok(None); |
| @@ -52,12 +52,12 @@ impl file::Store { · 13 unmodified lines | |||
| 52 | &self, | 52 | &self, |
| 53 | name: Name, | 53 | name: Name, |
| 54 | buf: &'b mut Vec<u8>, | 54 | buf: &'b mut Vec<u8>, |
| 55 | ) -> Result<Option<impl Iterator<Item = Result<log::Line<'b>, log::iter::decode::Error>>>, Error> | 55 | ) -> Result<Option<impl Iterator<Item = Result<log::LineRef<'b>, log::iter::decode::Error>>>, Error> |
| 56 | where | 56 | where |
| 57 | Name: TryInto<FullName<'a>, Error = E>, | 57 | Name: TryInto<FullNameRef<'a>, Error = E>, |
| 58 | crate::name::Error: From<E>, | 58 | crate::name::Error: From<E>, |
| 59 | { | 59 | { |
| 60 | let name: FullName<'_> = name.try_into().map_err(|err| Error::RefnameValidation(err.into()))?; | 60 | let name: FullNameRef<'_> = name.try_into().map_err(|err| Error::RefnameValidation(err.into()))?; |
| 61 | let path = self.reflog_path(name); | 61 | let path = self.reflog_path(name); |
| 62 | match std::fs::File::open(&path) { | 62 | match std::fs::File::open(&path) { |
| 63 | Ok(mut file) => { | 63 | Ok(mut file) => { |
| @@ -77,7 +77,7 @@ impl file::Store { · 13 unmodified lines | |||
| 77 | 77 | ||
| 78 | impl file::Store { | 78 | impl file::Store { |
| 79 | /// Implements the logic required to transform a fully qualified refname into its log name | 79 | /// Implements the logic required to transform a fully qualified refname into its log name |
| 80 | pub(crate) fn reflog_path(&self, name: FullName<'_>) -> PathBuf { | 80 | pub(crate) fn reflog_path(&self, name: FullNameRef<'_>) -> PathBuf { |
| 81 | self.reflog_path_inner(&name.to_path()) | 81 | self.reflog_path_inner(&name.to_path()) |
| 82 | } | 82 | } |
| 83 | } | 83 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | use super::*; | 1 | use super::*; |
| 2 | use crate::{file::WriteReflog, store::file::log, FullName}; | 2 | use crate::{file::WriteReflog, store::file::log, FullNameRef}; |
| 3 | use bstr::ByteSlice; | 3 | use bstr::ByteSlice; |
| 4 | use git_actor::{Sign, Signature, Time}; | 4 | use git_actor::{Sign, Signature, Time}; |
| 5 | use git_lock::acquire::Fail; | 5 | use git_lock::acquire::Fail; |
| @@ -16,7 +16,7 @@ fn empty_store(writemode: WriteReflog) -> Result<(TempDir, file::Store)> { · 10 unmodified lines | |||
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | fn reflock(store: &file::Store, full_name: &str) -> Result<git_lock::Marker> { | 18 | fn reflock(store: &file::Store, full_name: &str) -> Result<git_lock::Marker> { |
| 19 | let full_name: FullName<'_> = full_name.try_into()?; | 19 | let full_name: FullNameRef<'_> = full_name.try_into()?; |
| 20 | git_lock::Marker::acquire_to_hold_resource( | 20 | git_lock::Marker::acquire_to_hold_resource( |
| 21 | store.reference_path(&full_name.to_path()), | 21 | store.reference_path(&full_name.to_path()), |
| 22 | Fail::Immediately, | 22 | Fail::Immediately, |
| @@ -25,11 +25,11 @@ fn reflock(store: &file::Store, full_name: &str) -> Result<git_lock::Marker> { · 2 unmodified lines | |||
| 25 | .map_err(Into::into) | 25 | .map_err(Into::into) |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | fn reflog_lines(store: &file::Store, name: &str, buf: &mut Vec<u8>) -> Result<Vec<log::mutable::Line>> { | 28 | fn reflog_lines(store: &file::Store, name: &str, buf: &mut Vec<u8>) -> Result<Vec<log::Line>> { |
| 29 | store | 29 | store |
| 30 | .reflog_iter(name, buf)? | 30 | .reflog_iter(name, buf)? |
| 31 | .expect("existing reflog") | 31 | .expect("existing reflog") |
| 32 | .map(|l| l.map(log::mutable::Line::from)) | 32 | .map(|l| l.map(log::Line::from)) |
| 33 | .collect::<std::result::Result<Vec<_>, _>>() | 33 | .collect::<std::result::Result<Vec<_>, _>>() |
| 34 | .map_err(Into::into) | 34 | .map_err(Into::into) |
| 35 | } | 35 | } |
| @@ -83,7 +83,7 @@ fn missing_reflog_creates_it_even_if_similarly_named_empty_dir_exists_and_append · 47 unmodified lines | |||
| 83 | WriteReflog::Normal => { | 83 | WriteReflog::Normal => { |
| 84 | assert_eq!( | 84 | assert_eq!( |
| 85 | reflog_lines(&store, full_name, &mut buf)?, | 85 | reflog_lines(&store, full_name, &mut buf)?, |
| 86 | vec![log::mutable::Line { | 86 | vec![log::Line { |
| 87 | previous_oid: ObjectId::null_sha1(), | 87 | previous_oid: ObjectId::null_sha1(), |
| 88 | new_oid: new, | 88 | new_oid: new, |
| 89 | signature: committer.clone(), | 89 | signature: committer.clone(), |
| @@ -104,7 +104,7 @@ fn missing_reflog_creates_it_even_if_similarly_named_empty_dir_exists_and_append · 14 unmodified lines | |||
| 104 | assert_eq!(lines.len(), 2, "now there is another line"); | 104 | assert_eq!(lines.len(), 2, "now there is another line"); |
| 105 | assert_eq!( | 105 | assert_eq!( |
| 106 | lines.last().expect("non-empty"), | 106 | lines.last().expect("non-empty"), |
| 107 | &log::mutable::Line { | 107 | &log::Line { |
| 108 | previous_oid: previous, | 108 | previous_oid: previous, |
| 109 | new_oid: new, | 109 | new_oid: new, |
| 110 | signature: committer.clone(), | 110 | signature: committer.clone(), |
| @@ -7,8 +7,8 @@ use std::{ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | use crate::{ | 8 | use crate::{ |
| 9 | file::{loose, path_to_name, Reference}, | 9 | file::{loose, path_to_name, Reference}, |
| 10 | mutable::FullName, | ||
| 11 | store::{file, packed}, | 10 | store::{file, packed}, |
| 11 | FullName, | ||
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | /// An iterator stepping through sorted input of loose references and packed references, preferring loose refs over otherwise | 14 | /// An iterator stepping through sorted input of loose references and packed references, preferring loose refs over otherwise |
| @@ -5,13 +5,12 @@ use git_hash::ObjectId; · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | use crate::{ | 6 | use crate::{ |
| 7 | file::loose::reference::logiter::must_be_io_err, | 7 | file::loose::reference::logiter::must_be_io_err, |
| 8 | mutable, | ||
| 9 | store::{ | 8 | store::{ |
| 10 | file, | 9 | file, |
| 11 | file::{log, loose}, | 10 | file::{log, loose}, |
| 12 | packed, | 11 | packed, |
| 13 | }, | 12 | }, |
| 14 | FullName, Namespace, | 13 | FullNameRef, Namespace, Target, |
| 15 | }; | 14 | }; |
| 16 | 15 | ||
| 17 | /// Either a loose or packed reference, depending on where it was found. | 16 | /// Either a loose or packed reference, depending on where it was found. |
| @@ -82,7 +81,7 @@ impl<'p> Reference<'p> { · 64 unmodified lines | |||
| 82 | match self { | 81 | match self { |
| 83 | Reference::Loose(r) => r.follow_symbolic(store, packed), | 82 | Reference::Loose(r) => r.follow_symbolic(store, packed), |
| 84 | Reference::Packed(p) => packed | 83 | Reference::Packed(p) => packed |
| 85 | .and_then(|packed| packed.find(p.name).ok().flatten()) // needed to get data with 'p2 lifetime | 84 | .and_then(|packed| packed.try_find(p.name).ok().flatten()) // needed to get data with 'p2 lifetime |
| 86 | .and_then(|np| { | 85 | .and_then(|np| { |
| 87 | p.object.and(np.object).map(|peeled| { | 86 | p.object.and(np.object).map(|peeled| { |
| 88 | Ok(Reference::Packed(packed::Reference { | 87 | Ok(Reference::Packed(packed::Reference { |
| @@ -112,9 +111,9 @@ impl<'p> Reference<'p> { · 23 unmodified lines | |||
| 112 | &'a self, | 111 | &'a self, |
| 113 | store: &file::Store, | 112 | store: &file::Store, |
| 114 | buf: &'b mut Vec<u8>, | 113 | buf: &'b mut Vec<u8>, |
| 115 | ) -> std::io::Result<Option<impl Iterator<Item = Result<log::Line<'b>, log::iter::decode::Error>> + 'a>> { | 114 | ) -> std::io::Result<Option<impl Iterator<Item = Result<log::LineRef<'b>, log::iter::decode::Error>> + 'a>> { |
| 116 | match self { | 115 | match self { |
| 117 | Reference::Loose(r) => store.reflog_iter(r.name.borrow(), buf).map_err(must_be_io_err), | 116 | Reference::Loose(r) => store.reflog_iter(r.name.to_ref(), buf).map_err(must_be_io_err), |
| 118 | Reference::Packed(p) => store.reflog_iter(p.name, buf).map_err(must_be_io_err), | 117 | Reference::Packed(p) => store.reflog_iter(p.name, buf).map_err(must_be_io_err), |
| 119 | } | 118 | } |
| 120 | } | 119 | } |
| @@ -128,9 +127,9 @@ impl<'p> Reference<'p> { · 7 unmodified lines | |||
| 128 | } | 127 | } |
| 129 | 128 | ||
| 130 | /// Transform this reference into an owned `Target` | 129 | /// Transform this reference into an owned `Target` |
| 131 | pub fn into_target(self) -> mutable::Target { | 130 | pub fn into_target(self) -> Target { |
| 132 | match self { | 131 | match self { |
| 133 | Reference::Packed(p) => mutable::Target::Peeled(p.object()), | 132 | Reference::Packed(p) => Target::Peeled(p.object()), |
| 134 | Reference::Loose(r) => r.target, | 133 | Reference::Loose(r) => r.target, |
| 135 | } | 134 | } |
| 136 | } | 135 | } |
| @@ -144,28 +143,28 @@ impl<'p> Reference<'p> { · 7 unmodified lines | |||
| 144 | } | 143 | } |
| 145 | 144 | ||
| 146 | /// Return the full validated name of the reference, which may include a namespace. | 145 | /// Return the full validated name of the reference, which may include a namespace. |
| 147 | pub fn name(&self) -> FullName<'_> { | 146 | pub fn name(&self) -> FullNameRef<'_> { |
| 148 | match self { | 147 | match self { |
| 149 | Reference::Packed(p) => p.name, | 148 | Reference::Packed(p) => p.name, |
| 150 | Reference::Loose(l) => l.name.borrow(), | 149 | Reference::Loose(l) => l.name.to_ref(), |
| 151 | } | 150 | } |
| 152 | } | 151 | } |
| 153 | 152 | ||
| 154 | /// Return the full validated name of the reference, with the given namespace stripped if possible. | 153 | /// Return the full validated name of the reference, with the given namespace stripped if possible. |
| 155 | /// | 154 | /// |
| 156 | /// If the reference name wasn't prefixed with `namespace`, `None` is returned instead. | 155 | /// If the reference name wasn't prefixed with `namespace`, `None` is returned instead. |
| 157 | pub fn name_without_namespace(&self, namespace: &Namespace) -> Option<FullName<'_>> { | 156 | pub fn name_without_namespace(&self, namespace: &Namespace) -> Option<FullNameRef<'_>> { |
| 158 | self.name() | 157 | self.name() |
| 159 | .0 | 158 | .0 |
| 160 | .as_bstr() | 159 | .as_bstr() |
| 161 | .strip_prefix(namespace.0.as_bstr().as_ref()) | 160 | .strip_prefix(namespace.0.as_bstr().as_ref()) |
| 162 | .map(|stripped| FullName(stripped.as_bstr())) | 161 | .map(|stripped| FullNameRef(stripped.as_bstr())) |
| 163 | } | 162 | } |
| 164 | 163 | ||
| 165 | /// Return the target to which the reference points to. | 164 | /// Return the target to which the reference points to. |
| 166 | pub fn target(&self) -> mutable::Target { | 165 | pub fn target(&self) -> Target { |
| 167 | match self { | 166 | match self { |
| 168 | Reference::Packed(p) => mutable::Target::Peeled(p.target()), | 167 | Reference::Packed(p) => Target::Peeled(p.target()), |
| 169 | Reference::Loose(l) => l.target.clone(), | 168 | Reference::Loose(l) => l.target.clone(), |
| 170 | } | 169 | } |
| 171 | } | 170 | } |
| @@ -1,7 +1,7 @@ | |||
| 1 | use crate::{ | 1 | use crate::{ |
| 2 | mutable::Target, | ||
| 3 | store::file::{transaction::PackedRefs, Transaction}, | 2 | store::file::{transaction::PackedRefs, Transaction}, |
| 4 | transaction::{Change, LogChange, RefEdit, RefLog}, | 3 | transaction::{Change, LogChange, RefEdit, RefLog}, |
| 4 | Target, | ||
| 5 | }; | 5 | }; |
| 6 | 6 | ||
| 7 | impl<'s> Transaction<'s> { | 7 | impl<'s> Transaction<'s> { |
| @@ -102,7 +102,7 @@ impl<'s> Transaction<'s> { · 94 unmodified lines | |||
| 102 | Change::Delete { .. } => { | 102 | Change::Delete { .. } => { |
| 103 | // Reflog deletion happens first in case it fails a ref without log is less terrible than | 103 | // Reflog deletion happens first in case it fails a ref without log is less terrible than |
| 104 | // a log without a reference. | 104 | // a log without a reference. |
| 105 | let reflog_path = self.store.reflog_path(change.update.name.borrow()); | 105 | let reflog_path = self.store.reflog_path(change.update.name.to_ref()); |
| 106 | if let Err(err) = std::fs::remove_file(&reflog_path) { | 106 | if let Err(err) = std::fs::remove_file(&reflog_path) { |
| 107 | if err.kind() != std::io::ErrorKind::NotFound { | 107 | if err.kind() != std::io::ErrorKind::NotFound { |
| 108 | return Err(Error::DeleteReflog { | 108 | return Err(Error::DeleteReflog { |
| @@ -1,5 +1,4 @@ | |||
| 1 | use crate::{ | 1 | use crate::{ |
| 2 | mutable::Target, | ||
| 3 | packed, | 2 | packed, |
| 4 | store::{ | 3 | store::{ |
| 5 | file, | 4 | file, |
| @@ -10,6 +9,7 @@ use crate::{ · 4 unmodified lines | |||
| 10 | }, | 9 | }, |
| 11 | }, | 10 | }, |
| 12 | transaction::{Change, Create, LogChange, RefEdit, RefEditsExt, RefLog}, | 11 | transaction::{Change, Create, LogChange, RefEdit, RefEditsExt, RefLog}, |
| 12 | Target, | ||
| 13 | }; | 13 | }; |
| 14 | 14 | ||
| 15 | impl<'s> Transaction<'s> { | 15 | impl<'s> Transaction<'s> { |
| @@ -44,7 +44,7 @@ impl<'s> Transaction<'s> { · 28 unmodified lines | |||
| 44 | }) | 44 | }) |
| 45 | .and_then(|maybe_loose| match (maybe_loose, packed) { | 45 | .and_then(|maybe_loose| match (maybe_loose, packed) { |
| 46 | (None, Some(packed)) => packed | 46 | (None, Some(packed)) => packed |
| 47 | .find(change.update.name.borrow()) | 47 | .try_find(change.update.name.to_ref()) |
| 48 | .map(|opt| opt.map(file::Reference::Packed)) | 48 | .map(|opt| opt.map(file::Reference::Packed)) |
| 49 | .map_err(Error::from), | 49 | .map_err(Error::from), |
| 50 | (None, None) => Ok(None), | 50 | (None, None) => Ok(None), |
| @@ -104,7 +104,7 @@ impl<'s> Transaction<'s> { · 53 unmodified lines | |||
| 104 | 104 | ||
| 105 | let existing_ref = existing_ref?; | 105 | let existing_ref = existing_ref?; |
| 106 | match (&previous, &existing_ref) { | 106 | match (&previous, &existing_ref) { |
| 107 | (Create::Only, Some(existing)) if existing.target() != new.borrow() => { | 107 | (Create::Only, Some(existing)) if existing.target() != new.to_ref() => { |
| 108 | let new = new.clone(); | 108 | let new = new.clone(); |
| 109 | return Err(Error::MustNotExist { | 109 | return Err(Error::MustNotExist { |
| 110 | full_name: change.name(), | 110 | full_name: change.name(), |
| @@ -191,7 +191,7 @@ impl<'s> Transaction<'s> { · 80 unmodified lines | |||
| 191 | |name| { | 191 | |name| { |
| 192 | let symbolic_refs_are_never_packed = None; | 192 | let symbolic_refs_are_never_packed = None; |
| 193 | store | 193 | store |
| 194 | .find_existing(name, symbolic_refs_are_never_packed) | 194 | .find(name, symbolic_refs_are_never_packed) |
| 195 | .map(|r| r.into_target()) | 195 | .map(|r| r.into_target()) |
| 196 | .ok() | 196 | .ok() |
| 197 | }, | 197 | }, |
| @@ -321,7 +321,7 @@ impl<'s> Transaction<'s> { · 123 unmodified lines | |||
| 321 | 321 | ||
| 322 | // traverse parent chain from leaf/peeled ref and set the leaf previous oid accordingly | 322 | // traverse parent chain from leaf/peeled ref and set the leaf previous oid accordingly |
| 323 | // to help with their reflog entries | 323 | // to help with their reflog entries |
| 324 | if let (Some(crate::Target::Peeled(oid)), Some(parent_idx)) = | 324 | if let (Some(crate::TargetRef::Peeled(oid)), Some(parent_idx)) = |
| 325 | (change.update.change.previous_value(), change.parent_index) | 325 | (change.update.change.previous_value(), change.parent_index) |
| 326 | { | 326 | { |
| 327 | let oid = oid.to_owned(); | 327 | let oid = oid.to_owned(); |
| @@ -342,8 +342,8 @@ mod error { · 14 unmodified lines | |||
| 342 | use quick_error::quick_error; | 342 | use quick_error::quick_error; |
| 343 | 343 | ||
| 344 | use crate::{ | 344 | use crate::{ |
| 345 | mutable::Target, | ||
| 346 | store::{file, packed}, | 345 | store::{file, packed}, |
| 346 | Target, | ||
| 347 | }; | 347 | }; |
| 348 | 348 | ||
| 349 | quick_error! { | 349 | quick_error! { |
| @@ -73,7 +73,7 @@ pub fn reference<'a, E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], crate · 72 unmodified lines | |||
| 73 | ) -> IResult<&'a [u8], packed::Reference<'a>, E> { | 73 | ) -> IResult<&'a [u8], packed::Reference<'a>, E> { |
| 74 | let (input, (target, name)) = tuple(( | 74 | let (input, (target, name)) = tuple(( |
| 75 | terminated(hex_hash, tag(b" ")), | 75 | terminated(hex_hash, tag(b" ")), |
| 76 | map_res(until_newline, crate::FullName::try_from), | 76 | map_res(until_newline, crate::FullNameRef::try_from), |
| 77 | ))(input)?; | 77 | ))(input)?; |
| 78 | let (rest, object) = opt(delimited(tag(b"^"), hex_hash, newline))(input)?; | 78 | let (rest, object) = opt(delimited(tag(b"^"), hex_hash, newline))(input)?; |
| 79 | Ok((rest, packed::Reference { name, target, object })) | 79 | Ok((rest, packed::Reference { name, target, object })) |
| @@ -7,7 +7,7 @@ mod reference { · 6 unmodified lines | |||
| 7 | use super::Result; | 7 | use super::Result; |
| 8 | use crate::{ | 8 | use crate::{ |
| 9 | store::{packed, packed::decode}, | 9 | store::{packed, packed::decode}, |
| 10 | FullName, | 10 | FullNameRef, |
| 11 | }; | 11 | }; |
| 12 | 12 | ||
| 13 | #[test] | 13 | #[test] |
| @@ -28,7 +28,7 @@ mod reference { · 14 unmodified lines | |||
| 28 | assert_eq!( | 28 | assert_eq!( |
| 29 | parsed, | 29 | parsed, |
| 30 | packed::Reference { | 30 | packed::Reference { |
| 31 | name: FullName("refs/heads/alternates-after-packs-and-loose".into()), | 31 | name: FullNameRef("refs/heads/alternates-after-packs-and-loose".into()), |
| 32 | target: "d53c4b0f91f1b29769c9430f2d1c0bcab1170c75".into(), | 32 | target: "d53c4b0f91f1b29769c9430f2d1c0bcab1170c75".into(), |
| 33 | object: Some("e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37".into()) | 33 | object: Some("e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37".into()) |
| 34 | } | 34 | } |
| @@ -38,7 +38,7 @@ mod reference { · 3 unmodified lines | |||
| 38 | 38 | ||
| 39 | let (input, parsed) = decode::reference::<VerboseError<_>>(input)?; | 39 | let (input, parsed) = decode::reference::<VerboseError<_>>(input)?; |
| 40 | assert!(input.is_empty(), "exhausted"); | 40 | assert!(input.is_empty(), "exhausted"); |
| 41 | assert_eq!(parsed.name, FullName("refs/heads/avoid-double-lookup".into())); | 41 | assert_eq!(parsed.name, FullNameRef("refs/heads/avoid-double-lookup".into())); |
| 42 | assert_eq!(parsed.target, "eaae9c1bc723209d793eb93f5587fa2604d5cd92"); | 42 | assert_eq!(parsed.target, "eaae9c1bc723209d793eb93f5587fa2604d5cd92"); |
| 43 | assert!(parsed.object.is_none()); | 43 | assert!(parsed.object.is_none()); |
| 44 | Ok(()) | 44 | Ok(()) |
| @@ -2,14 +2,14 @@ use std::{borrow::Cow, convert::TryInto}; · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | use bstr::{BStr, BString, ByteSlice}; | 3 | use bstr::{BStr, BString, ByteSlice}; |
| 4 | 4 | ||
| 5 | use crate::{store::packed, PartialName}; | 5 | use crate::{store::packed, PartialNameRef}; |
| 6 | 6 | ||
| 7 | /// packed-refs specific functionality | 7 | /// packed-refs specific functionality |
| 8 | impl packed::Buffer { | 8 | impl packed::Buffer { |
| 9 | /// Find a reference with the given `name` and return it. | 9 | /// Find a reference with the given `name` and return it. |
| 10 | pub fn find<'a, Name, E>(&self, name: Name) -> Result<Option<packed::Reference<'_>>, Error> | 10 | pub fn try_find<'a, Name, E>(&self, name: Name) -> Result<Option<packed::Reference<'_>>, Error> |
| 11 | where | 11 | where |
| 12 | Name: TryInto<PartialName<'a>, Error = E>, | 12 | Name: TryInto<PartialNameRef<'a>, Error = E>, |
| 13 | Error: From<E>, | 13 | Error: From<E>, |
| 14 | { | 14 | { |
| 15 | let name = name.try_into()?; | 15 | let name = name.try_into()?; |
| @@ -52,12 +52,12 @@ impl packed::Buffer { · 36 unmodified lines | |||
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | /// Find a reference with the given `name` and return it. | 54 | /// Find a reference with the given `name` and return it. |
| 55 | pub fn find_existing<'a, Name, E>(&self, name: Name) -> Result<packed::Reference<'_>, existing::Error> | 55 | pub fn find<'a, Name, E>(&self, name: Name) -> Result<packed::Reference<'_>, existing::Error> |
| 56 | where | 56 | where |
| 57 | Name: TryInto<PartialName<'a>, Error = E>, | 57 | Name: TryInto<PartialNameRef<'a>, Error = E>, |
| 58 | Error: From<E>, | 58 | Error: From<E>, |
| 59 | { | 59 | { |
| 60 | match self.find(name) { | 60 | match self.try_find(name) { |
| 61 | Ok(Some(r)) => Ok(r), | 61 | Ok(Some(r)) => Ok(r), |
| 62 | Ok(None) => Err(existing::Error::NotFound), | 62 | Ok(None) => Err(existing::Error::NotFound), |
| 63 | Err(err) => Err(existing::Error::Find(err)), | 63 | Err(err) => Err(existing::Error::Find(err)), |
| @@ -4,7 +4,7 @@ use bstr::{BStr, BString}; · 3 unmodified lines | |||
| 4 | use filebuffer::FileBuffer; | 4 | use filebuffer::FileBuffer; |
| 5 | use git_hash::ObjectId; | 5 | use git_hash::ObjectId; |
| 6 | 6 | ||
| 7 | use crate::{transaction::RefEdit, FullName}; | 7 | use crate::{transaction::RefEdit, FullNameRef}; |
| 8 | 8 | ||
| 9 | enum Backing { | 9 | enum Backing { |
| 10 | /// The buffer is loaded entirely in memory, along with the `offset` to the first record past the header. | 10 | /// The buffer is loaded entirely in memory, along with the `offset` to the first record past the header. |
| @@ -42,7 +42,7 @@ pub(crate) struct Transaction { · 31 unmodified lines | |||
| 42 | #[derive(Debug, PartialEq, Eq)] | 42 | #[derive(Debug, PartialEq, Eq)] |
| 43 | pub struct Reference<'a> { | 43 | pub struct Reference<'a> { |
| 44 | /// The validated full name of the reference. | 44 | /// The validated full name of the reference. |
| 45 | pub name: FullName<'a>, | 45 | pub name: FullNameRef<'a>, |
| 46 | /// The target object id of the reference, hex encoded. | 46 | /// The target object id of the reference, hex encoded. |
| 47 | pub target: &'a BStr, | 47 | pub target: &'a BStr, |
| 48 | /// The fully peeled object id, hex encoded, that the ref is ultimately pointing to | 48 | /// The fully peeled object id, hex encoded, that the ref is ultimately pointing to |
| @@ -1,9 +1,9 @@ | |||
| 1 | use std::io::Write; | 1 | use std::io::Write; |
| 2 | 2 | ||
| 3 | use crate::{ | 3 | use crate::{ |
| 4 | mutable::Target, | ||
| 5 | store::{file::transaction::FindObjectFn, packed, packed::Edit}, | 4 | store::{file::transaction::FindObjectFn, packed, packed::Edit}, |
| 6 | transaction::{Change, RefEdit}, | 5 | transaction::{Change, RefEdit}, |
| 6 | Target, | ||
| 7 | }; | 7 | }; |
| 8 | 8 | ||
| 9 | pub(crate) const HEADER_LINE: &[u8] = b"# pack-refs with: peeled fully-peeled sorted \n"; | 9 | pub(crate) const HEADER_LINE: &[u8] = b"# pack-refs with: peeled fully-peeled sorted \n"; |
| @@ -54,9 +54,7 @@ impl packed::Transaction { · 44 unmodified lines | |||
| 54 | .into_iter() | 54 | .into_iter() |
| 55 | .filter(|edit| { | 55 | .filter(|edit| { |
| 56 | if let Change::Delete { .. } = edit.change { | 56 | if let Change::Delete { .. } = edit.change { |
| 57 | buffer | 57 | buffer.as_ref().map_or(true, |b| b.find(edit.name.to_ref()).is_ok()) |
| 58 | .as_ref() | ||
| 59 | .map_or(true, |b| b.find_existing(edit.name.borrow()).is_ok()) | ||
| 60 | } else { | 58 | } else { |
| 61 | true | 59 | true |
| 62 | } | 60 | } |
| @@ -1,9 +1,38 @@ | |||
| 1 | use bstr::BStr; | 1 | use bstr::{BStr, ByteSlice}; |
| 2 | use git_hash::oid; | 2 | use git_hash::{oid, ObjectId}; |
| 3 | use std::fmt; | ||
| 3 | 4 | ||
| 4 | use crate::{Kind, Target}; | 5 | use crate::{FullName, Kind, Target, TargetRef}; |
| 5 | 6 | ||
| 6 | impl<'a> Target<'a> { | 7 | impl<'a> TargetRef<'a> { |
| 8 | /// Returns the kind of the target the ref is pointing to. | ||
| 9 | pub fn kind(&self) -> Kind { | ||
| 10 | match self { | ||
| 11 | TargetRef::Symbolic(_) => Kind::Symbolic, | ||
| 12 | TargetRef::Peeled(_) => Kind::Peeled, | ||
| 13 | } | ||
| 14 | } | ||
| 15 | /// Interpret this target as object id which maybe `None` if it is symbolic. | ||
| 16 | pub fn as_id(&self) -> Option<&oid> { | ||
| 17 | match self { | ||
| 18 | TargetRef::Symbolic(_) => None, | ||
| 19 | TargetRef::Peeled(oid) => Some(oid), | ||
| 20 | } | ||
| 21 | } | ||
| 22 | /// Interpret this target as name of the reference it points to which maybe `None` if it an object id. | ||
| 23 | pub fn as_name(&self) -> Option<&BStr> { | ||
| 24 | match self { | ||
| 25 | TargetRef::Symbolic(path) => Some(path), | ||
| 26 | TargetRef::Peeled(_) => None, | ||
| 27 | } | ||
| 28 | } | ||
| 29 | /// Convert this instance into an owned version, without consuming it. | ||
| 30 | pub fn into_owned(self) -> crate::Target { | ||
| 31 | self.into() | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | impl Target { | ||
| 7 | /// Returns the kind of the target the ref is pointing to. | 36 | /// Returns the kind of the target the ref is pointing to. |
| 8 | pub fn kind(&self) -> Kind { | 37 | pub fn kind(&self) -> Kind { |
| 9 | match self { | 38 | match self { |
| @@ -11,6 +40,23 @@ impl<'a> Target<'a> { · 1 unmodified line | |||
| 11 | Target::Peeled(_) => Kind::Peeled, | 40 | Target::Peeled(_) => Kind::Peeled, |
| 12 | } | 41 | } |
| 13 | } | 42 | } |
| 43 | |||
| 44 | /// Return true if this is a peeled target with a null hash | ||
| 45 | pub fn is_null(&self) -> bool { | ||
| 46 | match self { | ||
| 47 | Target::Peeled(oid) => oid.is_null(), | ||
| 48 | Target::Symbolic(_) => false, | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | /// Interpret this owned Target as shared Target | ||
| 53 | pub fn to_ref(&self) -> crate::TargetRef<'_> { | ||
| 54 | match self { | ||
| 55 | Target::Peeled(oid) => crate::TargetRef::Peeled(oid), | ||
| 56 | Target::Symbolic(name) => crate::TargetRef::Symbolic(name.0.as_bstr()), | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 14 | /// Interpret this target as object id which maybe `None` if it is symbolic. | 60 | /// Interpret this target as object id which maybe `None` if it is symbolic. |
| 15 | pub fn as_id(&self) -> Option<&oid> { | 61 | pub fn as_id(&self) -> Option<&oid> { |
| 16 | match self { | 62 | match self { |
| @@ -21,12 +67,41 @@ impl<'a> Target<'a> { · 4 unmodified lines | |||
| 21 | /// Interpret this target as name of the reference it points to which maybe `None` if it an object id. | 67 | /// Interpret this target as name of the reference it points to which maybe `None` if it an object id. |
| 22 | pub fn as_name(&self) -> Option<&BStr> { | 68 | pub fn as_name(&self) -> Option<&BStr> { |
| 23 | match self { | 69 | match self { |
| 24 | Target::Symbolic(path) => Some(path), | 70 | Target::Symbolic(name) => Some(name.as_bstr()), |
| 25 | Target::Peeled(_) => None, | 71 | Target::Peeled(_) => None, |
| 26 | } | 72 | } |
| 27 | } | 73 | } |
| 28 | /// Convert this instance into an owned version, without consuming it. | 74 | |
| 29 | pub fn to_owned(self) -> crate::mutable::Target { | 75 | /// Create an instance that signals that a reference should exist if this value is used in a [`Change`][crate::transaction::Change]. |
| 30 | self.into() | 76 | pub fn must_exist() -> Self { |
| 77 | Target::Peeled(ObjectId::null_sha1()) | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | impl<'a> From<crate::TargetRef<'a>> for Target { | ||
| 82 | fn from(src: crate::TargetRef<'a>) -> Self { | ||
| 83 | match src { | ||
| 84 | crate::TargetRef::Peeled(oid) => Target::Peeled(oid.to_owned()), | ||
| 85 | crate::TargetRef::Symbolic(name) => Target::Symbolic(FullName(name.to_owned())), | ||
| 86 | } | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | impl<'a> PartialEq<crate::TargetRef<'a>> for Target { | ||
| 91 | fn eq(&self, other: &crate::TargetRef<'a>) -> bool { | ||
| 92 | match (self, other) { | ||
| 93 | (Target::Peeled(lhs), crate::TargetRef::Peeled(rhs)) => lhs == rhs, | ||
| 94 | (Target::Symbolic(lhs), crate::TargetRef::Symbolic(rhs)) => lhs.as_bstr() == *rhs, | ||
| 95 | _ => false, | ||
| 96 | } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | impl fmt::Display for Target { | ||
| 101 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| 102 | match self { | ||
| 103 | Target::Peeled(oid) => oid.fmt(f), | ||
| 104 | Target::Symbolic(name) => write!(f, "ref: {}", name.as_bstr()), | ||
| 105 | } | ||
| 31 | } | 106 | } |
| 32 | } | 107 | } |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | |||
| 15 | use bstr::BString; | 15 | use bstr::BString; |
| 16 | use git_hash::ObjectId; | 16 | use git_hash::ObjectId; |
| 17 | 17 | ||
| 18 | use crate::mutable::{FullName, Target}; | 18 | use crate::{FullName, Target}; |
| 19 | 19 | ||
| 20 | /// A change to the reflog. | 20 | /// A change to the reflog. |
| 21 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] | 21 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] |
| @@ -101,14 +101,14 @@ pub enum Change { · 79 unmodified lines | |||
| 101 | 101 | ||
| 102 | impl Change { | 102 | impl Change { |
| 103 | /// Return references to values that are in common between all variants. | 103 | /// Return references to values that are in common between all variants. |
| 104 | pub fn previous_value(&self) -> Option<crate::Target<'_>> { | 104 | pub fn previous_value(&self) -> Option<crate::TargetRef<'_>> { |
| 105 | match self { | 105 | match self { |
| 106 | Change::Update { mode: Create::Only, .. } => None, | 106 | Change::Update { mode: Create::Only, .. } => None, |
| 107 | Change::Update { | 107 | Change::Update { |
| 108 | mode: Create::OrUpdate { previous }, | 108 | mode: Create::OrUpdate { previous }, |
| 109 | .. | 109 | .. |
| 110 | } | 110 | } |
| 111 | | Change::Delete { previous, .. } => previous.as_ref().map(|t| t.borrow()), | 111 | | Change::Delete { previous, .. } => previous.as_ref().map(|t| t.to_ref()), |
| 112 | } | 112 | } |
| 113 | } | 113 | } |
| 114 | } | 114 | } |
| @@ -139,7 +139,7 @@ mod ext { · 24 unmodified lines | |||
| 139 | 139 | ||
| 140 | use crate::{ | 140 | use crate::{ |
| 141 | transaction::{Change, LogChange, RefEdit, RefLog, Target}, | 141 | transaction::{Change, LogChange, RefEdit, RefLog, Target}, |
| 142 | Namespace, PartialName, | 142 | Namespace, PartialNameRef, |
| 143 | }; | 143 | }; |
| 144 | 144 | ||
| 145 | /// An extension trait to perform commonly used operations on edits across different ref stores. | 145 | /// An extension trait to perform commonly used operations on edits across different ref stores. |
| @@ -155,7 +155,7 @@ mod ext { · 9 unmodified lines | |||
| 155 | /// Note no action is performed if deref isn't specified. | 155 | /// Note no action is performed if deref isn't specified. |
| 156 | fn extend_with_splits_of_symbolic_refs( | 156 | fn extend_with_splits_of_symbolic_refs( |
| 157 | &mut self, | 157 | &mut self, |
| 158 | find: impl FnMut(PartialName<'_>) -> Option<Target>, | 158 | find: impl FnMut(PartialNameRef<'_>) -> Option<Target>, |
| 159 | make_entry: impl FnMut(usize, RefEdit) -> T, | 159 | make_entry: impl FnMut(usize, RefEdit) -> T, |
| 160 | ) -> Result<(), std::io::Error>; | 160 | ) -> Result<(), std::io::Error>; |
| 161 | 161 | ||
| @@ -168,7 +168,7 @@ mod ext { · 6 unmodified lines | |||
| 168 | /// Users call this to assure derefs are honored and duplicate checks are done. | 168 | /// Users call this to assure derefs are honored and duplicate checks are done. |
| 169 | fn pre_process( | 169 | fn pre_process( |
| 170 | &mut self, | 170 | &mut self, |
| 171 | find: impl FnMut(PartialName<'_>) -> Option<Target>, | 171 | find: impl FnMut(PartialNameRef<'_>) -> Option<Target>, |
| 172 | make_entry: impl FnMut(usize, RefEdit) -> T, | 172 | make_entry: impl FnMut(usize, RefEdit) -> T, |
| 173 | namespace: impl Into<Option<Namespace>>, | 173 | namespace: impl Into<Option<Namespace>>, |
| 174 | ) -> Result<(), std::io::Error> { | 174 | ) -> Result<(), std::io::Error> { |
| @@ -198,7 +198,7 @@ mod ext { · 23 unmodified lines | |||
| 198 | 198 | ||
| 199 | fn extend_with_splits_of_symbolic_refs( | 199 | fn extend_with_splits_of_symbolic_refs( |
| 200 | &mut self, | 200 | &mut self, |
| 201 | mut find: impl FnMut(PartialName<'_>) -> Option<Target>, | 201 | mut find: impl FnMut(PartialNameRef<'_>) -> Option<Target>, |
| 202 | mut make_entry: impl FnMut(usize, RefEdit) -> E, | 202 | mut make_entry: impl FnMut(usize, RefEdit) -> E, |
| 203 | ) -> Result<(), std::io::Error> { | 203 | ) -> Result<(), std::io::Error> { |
| 204 | let mut new_edits = Vec::new(); | 204 | let mut new_edits = Vec::new(); |
| @@ -6,7 +6,7 @@ mod line { · 5 unmodified lines | |||
| 6 | #[test] | 6 | #[test] |
| 7 | fn newlines_in_message_of_the_input_fails_and_we_trust_signature_writing_validation() -> crate::Result { | 7 | fn newlines_in_message_of_the_input_fails_and_we_trust_signature_writing_validation() -> crate::Result { |
| 8 | let line = "0000000000000000000000000000000000000000 134385f6d781b7e97062102c6a483440bfda2a03 committer <committer@example.com> 946771200 +0000 commit (initial): c1"; | 8 | let line = "0000000000000000000000000000000000000000 134385f6d781b7e97062102c6a483440bfda2a03 committer <committer@example.com> 946771200 +0000 commit (initial): c1"; |
| 9 | let mut line = log::Line::from_bytes(line.as_bytes())?.to_mutable(); | 9 | let mut line = log::LineRef::from_bytes(line.as_bytes())?.to_owned(); |
| 10 | line.message.push_str("and here come\nthe newline"); | 10 | line.message.push_str("and here come\nthe newline"); |
| 11 | let err = line | 11 | let err = line |
| 12 | .write_to(&mut Vec::new()) | 12 | .write_to(&mut Vec::new()) |
| @@ -20,10 +20,10 @@ mod line { · 7 unmodified lines | |||
| 20 | let lines = &["0000000000000000000000000000000000000000 134385f6d781b7e97062102c6a483440bfda2a03 committer <committer@example.com> 946771200 +0000 commit (initial): c1\n", | 20 | let lines = &["0000000000000000000000000000000000000000 134385f6d781b7e97062102c6a483440bfda2a03 committer <committer@example.com> 946771200 +0000 commit (initial): c1\n", |
| 21 | "0000000000000000000000000000000000000000 134385f6d781b7e97062102c6a483440bfda2a03 committer <committer@example.com> 946771200 +0000 \n"]; | 21 | "0000000000000000000000000000000000000000 134385f6d781b7e97062102c6a483440bfda2a03 committer <committer@example.com> 946771200 +0000 \n"]; |
| 22 | for line in lines { | 22 | for line in lines { |
| 23 | let line = log::Line::from_bytes(line.as_bytes())?; | 23 | let line = log::LineRef::from_bytes(line.as_bytes())?; |
| 24 | let mut buf = Vec::new(); | 24 | let mut buf = Vec::new(); |
| 25 | line.to_mutable().write_to(&mut buf)?; | 25 | line.to_owned().write_to(&mut buf)?; |
| 26 | let same_line = log::Line::from_bytes(&buf)?; | 26 | let same_line = log::LineRef::from_bytes(&buf)?; |
| 27 | assert_eq!(line, same_line); | 27 | assert_eq!(line, same_line); |
| 28 | } | 28 | } |
| 29 | Ok(()) | 29 | Ok(()) |
| @@ -75,7 +75,7 @@ mod iter { · 45 unmodified lines | |||
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | mod with_buffer_big_enough_for_largest_line { | 77 | mod with_buffer_big_enough_for_largest_line { |
| 78 | use git_ref::file::log::mutable::Line; | 78 | use git_ref::file::log::Line; |
| 79 | use git_testtools::hex_to_id; | 79 | use git_testtools::hex_to_id; |
| 80 | 80 | ||
| 81 | #[test] | 81 | #[test] |
| @@ -6,7 +6,7 @@ mod reflog { · 5 unmodified lines | |||
| 6 | fn iter() -> crate::Result { | 6 | fn iter() -> crate::Result { |
| 7 | let store = file::store_with_packed_refs()?; | 7 | let store = file::store_with_packed_refs()?; |
| 8 | let packed = store.packed_buffer()?; | 8 | let packed = store.packed_buffer()?; |
| 9 | let r = store.find_existing("main", packed.as_ref())?; | 9 | let r = store.find("main", packed.as_ref())?; |
| 10 | let mut buf = Vec::new(); | 10 | let mut buf = Vec::new(); |
| 11 | assert_eq!(r.log_iter(&store, &mut buf)?.expect("log exists").count(), 1); | 11 | assert_eq!(r.log_iter(&store, &mut buf)?.expect("log exists").count(), 1); |
| 12 | assert!(r.log_exists(&store), "it exists if its readable"); | 12 | assert!(r.log_exists(&store), "it exists if its readable"); |
| @@ -17,7 +17,7 @@ mod reflog { · 4 unmodified lines | |||
| 17 | fn iter_rev() -> crate::Result { | 17 | fn iter_rev() -> crate::Result { |
| 18 | let store = file::store_with_packed_refs()?; | 18 | let store = file::store_with_packed_refs()?; |
| 19 | let packed = store.packed_buffer()?; | 19 | let packed = store.packed_buffer()?; |
| 20 | let r = store.find_existing("main", packed.as_ref())?; | 20 | let r = store.find("main", packed.as_ref())?; |
| 21 | let mut buf = [0u8; 256]; | 21 | let mut buf = [0u8; 256]; |
| 22 | assert_eq!(r.log_iter_rev(&store, &mut buf)?.expect("log exists").count(), 1); | 22 | assert_eq!(r.log_iter_rev(&store, &mut buf)?.expect("log exists").count(), 1); |
| 23 | Ok(()) | 23 | Ok(()) |
| @@ -30,7 +30,7 @@ mod reflog { · 6 unmodified lines | |||
| 30 | #[test] | 30 | #[test] |
| 31 | fn iter() -> crate::Result { | 31 | fn iter() -> crate::Result { |
| 32 | let store = file::store()?; | 32 | let store = file::store()?; |
| 33 | let r = store.loose_find_existing("HEAD")?; | 33 | let r = store.find_loose("HEAD")?; |
| 34 | let mut buf = Vec::new(); | 34 | let mut buf = Vec::new(); |
| 35 | assert_eq!(r.log_iter(&store, &mut buf)?.expect("log exists").count(), 1); | 35 | assert_eq!(r.log_iter(&store, &mut buf)?.expect("log exists").count(), 1); |
| 36 | assert!(r.log_exists(&store), "it exists if its readable"); | 36 | assert!(r.log_exists(&store), "it exists if its readable"); |
| @@ -40,7 +40,7 @@ mod reflog { · 3 unmodified lines | |||
| 40 | #[test] | 40 | #[test] |
| 41 | fn iter_rev() -> crate::Result { | 41 | fn iter_rev() -> crate::Result { |
| 42 | let store = file::store()?; | 42 | let store = file::store()?; |
| 43 | let r = store.loose_find_existing("HEAD")?; | 43 | let r = store.find_loose("HEAD")?; |
| 44 | let mut buf = [0u8; 256]; | 44 | let mut buf = [0u8; 256]; |
| 45 | assert_eq!(r.log_iter_rev(&store, &mut buf)?.expect("log exists").count(), 1); | 45 | assert_eq!(r.log_iter_rev(&store, &mut buf)?.expect("log exists").count(), 1); |
| 46 | Ok(()) | 46 | Ok(()) |
| @@ -60,7 +60,7 @@ mod peel { · 13 unmodified lines | |||
| 60 | #[test] | 60 | #[test] |
| 61 | fn one_level() -> crate::Result { | 61 | fn one_level() -> crate::Result { |
| 62 | let store = file::store()?; | 62 | let store = file::store()?; |
| 63 | let r = store.loose_find_existing("HEAD")?; | 63 | let r = store.find_loose("HEAD")?; |
| 64 | assert_eq!(r.kind(), git_ref::Kind::Symbolic, "there is something to peel"); | 64 | assert_eq!(r.kind(), git_ref::Kind::Symbolic, "there is something to peel"); |
| 65 | 65 | ||
| 66 | let nr = git_ref::file::loose::Reference::try_from( | 66 | let nr = git_ref::file::loose::Reference::try_from( |
| @@ -68,13 +68,13 @@ mod peel { · 1 unmodified line | |||
| 68 | ) | 68 | ) |
| 69 | .expect("loose ref"); | 69 | .expect("loose ref"); |
| 70 | assert!( | 70 | assert!( |
| 71 | matches!(nr.target.borrow(), git_ref::Target::Peeled(_)), | 71 | matches!(nr.target.to_ref(), git_ref::TargetRef::Peeled(_)), |
| 72 | "iteration peels a single level" | 72 | "iteration peels a single level" |
| 73 | ); | 73 | ); |
| 74 | assert!(nr.follow_symbolic(&store, None).is_none(), "end of iteration"); | 74 | assert!(nr.follow_symbolic(&store, None).is_none(), "end of iteration"); |
| 75 | assert_eq!( | 75 | assert_eq!( |
| 76 | nr.target.borrow(), | 76 | nr.target.to_ref(), |
| 77 | git_ref::Target::Peeled(&hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03")), | 77 | git_ref::TargetRef::Peeled(&hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03")), |
| 78 | "we still have the peeled target" | 78 | "we still have the peeled target" |
| 79 | ); | 79 | ); |
| 80 | Ok(()) | 80 | Ok(()) |
| @@ -83,13 +83,13 @@ mod peel { · 2 unmodified lines | |||
| 83 | #[test] | 83 | #[test] |
| 84 | fn peel_with_packed_involvement() -> crate::Result { | 84 | fn peel_with_packed_involvement() -> crate::Result { |
| 85 | let store = store_with_packed_refs()?; | 85 | let store = store_with_packed_refs()?; |
| 86 | let mut head = store.loose_find_existing("HEAD")?; | 86 | let mut head = store.find_loose("HEAD")?; |
| 87 | let packed = store.packed_buffer()?; | 87 | let packed = store.packed_buffer()?; |
| 88 | let expected = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); | 88 | let expected = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); |
| 89 | assert_eq!(head.peel_to_id_in_place(&store, packed.as_ref(), peel::none)?, expected); | 89 | assert_eq!(head.peel_to_id_in_place(&store, packed.as_ref(), peel::none)?, expected); |
| 90 | assert_eq!(head.target.as_id().map(ToOwned::to_owned), Some(expected)); | 90 | assert_eq!(head.target.as_id().map(ToOwned::to_owned), Some(expected)); |
| 91 | 91 | ||
| 92 | let mut head = store.find_existing("dt1", packed.as_ref())?; | 92 | let mut head = store.find("dt1", packed.as_ref())?; |
| 93 | assert_eq!(head.peel_to_id_in_place(&store, packed.as_ref(), peel::none)?, expected); | 93 | assert_eq!(head.peel_to_id_in_place(&store, packed.as_ref(), peel::none)?, expected); |
| 94 | assert_eq!(head.target().as_id().map(ToOwned::to_owned), Some(expected)); | 94 | assert_eq!(head.target().as_id().map(ToOwned::to_owned), Some(expected)); |
| 95 | Ok(()) | 95 | Ok(()) |
| @@ -100,7 +100,7 @@ mod peel { · 4 unmodified lines | |||
| 100 | let store = store_with_packed_refs()?; | 100 | let store = store_with_packed_refs()?; |
| 101 | let packed = store.packed_buffer()?; | 101 | let packed = store.packed_buffer()?; |
| 102 | 102 | ||
| 103 | let head = store.find_existing("dt1", packed.as_ref())?; | 103 | let head = store.find("dt1", packed.as_ref())?; |
| 104 | assert!(head.is_packed()); | 104 | assert!(head.is_packed()); |
| 105 | assert_eq!( | 105 | assert_eq!( |
| 106 | head.target().as_id().map(ToOwned::to_owned), | 106 | head.target().as_id().map(ToOwned::to_owned), |
| @@ -128,14 +128,14 @@ mod peel { · 21 unmodified lines | |||
| 128 | #[test] | 128 | #[test] |
| 129 | fn to_id_multi_hop() -> crate::Result { | 129 | fn to_id_multi_hop() -> crate::Result { |
| 130 | let store = file::store()?; | 130 | let store = file::store()?; |
| 131 | let mut r = store.loose_find_existing("multi-link")?; | 131 | let mut r = store.find_loose("multi-link")?; |
| 132 | assert_eq!(r.kind(), git_ref::Kind::Symbolic, "there is something to peel"); | 132 | assert_eq!(r.kind(), git_ref::Kind::Symbolic, "there is something to peel"); |
| 133 | 133 | ||
| 134 | let commit = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); | 134 | let commit = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); |
| 135 | assert_eq!(r.peel_to_id_in_place(&store, None, peel::none)?, commit); | 135 | assert_eq!(r.peel_to_id_in_place(&store, None, peel::none)?, commit); |
| 136 | assert_eq!(r.name.as_bstr(), "refs/remotes/origin/multi-link-target3"); | 136 | assert_eq!(r.name.as_bstr(), "refs/remotes/origin/multi-link-target3"); |
| 137 | 137 | ||
| 138 | let mut r = store.loose_find_existing("dt1")?; | 138 | let mut r = store.find_loose("dt1")?; |
| 139 | assert_eq!( | 139 | assert_eq!( |
| 140 | r.peel_to_id_in_place(&store, None, peel::none)?, | 140 | r.peel_to_id_in_place(&store, None, peel::none)?, |
| 141 | hex_to_id("4c3f4cce493d7beb45012e478021b5f65295e5a3"), | 141 | hex_to_id("4c3f4cce493d7beb45012e478021b5f65295e5a3"), |
| @@ -158,7 +158,7 @@ mod peel { · 16 unmodified lines | |||
| 158 | #[test] | 158 | #[test] |
| 159 | fn to_id_cycle() -> crate::Result { | 159 | fn to_id_cycle() -> crate::Result { |
| 160 | let store = file::store()?; | 160 | let store = file::store()?; |
| 161 | let mut r = store.loose_find_existing("loop-a")?; | 161 | let mut r = store.find_loose("loop-a")?; |
| 162 | assert_eq!(r.kind(), git_ref::Kind::Symbolic, "there is something to peel"); | 162 | assert_eq!(r.kind(), git_ref::Kind::Symbolic, "there is something to peel"); |
| 163 | assert_eq!(r.name.as_bstr(), "refs/loop-a"); | 163 | assert_eq!(r.name.as_bstr(), "refs/loop-a"); |
| 164 | 164 | ||
| @@ -203,8 +203,8 @@ mod parse { · 38 unmodified lines | |||
| 203 | let reference = | 203 | let reference = |
| 204 | Reference::try_from_path("HEAD".try_into().expect("valid static name"), $input).unwrap(); | 204 | Reference::try_from_path("HEAD".try_into().expect("valid static name"), $input).unwrap(); |
| 205 | assert_eq!(reference.kind(), $kind); | 205 | assert_eq!(reference.kind(), $kind); |
| 206 | assert_eq!(reference.target.borrow().as_id(), $id); | 206 | assert_eq!(reference.target.to_ref().as_id(), $id); |
| 207 | assert_eq!(reference.target.borrow().as_name(), $ref); | 207 | assert_eq!(reference.target.to_ref().as_name(), $ref); |
| 208 | } | 208 | } |
| 209 | }; | 209 | }; |
| 210 | } | 210 | } |
| @@ -8,8 +8,8 @@ mod existing { · 7 unmodified lines | |||
| 8 | let store = store_at("make_packed_ref_repository_for_overlay.sh")?; | 8 | let store = store_at("make_packed_ref_repository_for_overlay.sh")?; |
| 9 | let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); | 9 | let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); |
| 10 | let packed = store.packed_buffer()?; | 10 | let packed = store.packed_buffer()?; |
| 11 | let r = store.find_existing("main", packed.as_ref())?; | 11 | let r = store.find("main", packed.as_ref())?; |
| 12 | assert_eq!(r.target().borrow().as_id().expect("peeled"), c1); | 12 | assert_eq!(r.target().to_ref().as_id().expect("peeled"), c1); |
| 13 | assert_eq!(r.name().as_bstr(), "refs/heads/main"); | 13 | assert_eq!(r.name().as_bstr(), "refs/heads/main"); |
| 14 | Ok(()) | 14 | Ok(()) |
| 15 | } | 15 | } |
| @@ -27,7 +27,7 @@ mod loose { · 11 unmodified lines | |||
| 27 | fn success_and_failure() -> crate::Result { | 27 | fn success_and_failure() -> crate::Result { |
| 28 | let store = store()?; | 28 | let store = store()?; |
| 29 | for (partial_name, expected_path) in &[("main", Some("refs/heads/main")), ("does-not-exist", None)] { | 29 | for (partial_name, expected_path) in &[("main", Some("refs/heads/main")), ("does-not-exist", None)] { |
| 30 | let reference = store.loose_find_existing(*partial_name); | 30 | let reference = store.find_loose(*partial_name); |
| 31 | match expected_path { | 31 | match expected_path { |
| 32 | Some(expected_path) => assert_eq!(reference?.name.as_bstr(), expected_path), | 32 | Some(expected_path) => assert_eq!(reference?.name.as_bstr(), expected_path), |
| 33 | None => match reference { | 33 | None => match reference { |
| @@ -60,9 +60,9 @@ mod loose { · 26 unmodified lines | |||
| 60 | ("heads/main", "refs/heads/main", git_ref::Kind::Peeled), | 60 | ("heads/main", "refs/heads/main", git_ref::Kind::Peeled), |
| 61 | ("refs/heads/main", "refs/heads/main", git_ref::Kind::Peeled), | 61 | ("refs/heads/main", "refs/heads/main", git_ref::Kind::Peeled), |
| 62 | ] { | 62 | ] { |
| 63 | let reference = store.loose_find(*partial_name)?.expect("exists"); | 63 | let reference = store.try_find_loose(*partial_name)?.expect("exists"); |
| 64 | assert_eq!(reference.name.as_bstr(), expected_path); | 64 | assert_eq!(reference.name.as_bstr(), expected_path); |
| 65 | assert_eq!(reference.target.borrow().kind(), *expected_ref_kind); | 65 | assert_eq!(reference.target.to_ref().kind(), *expected_ref_kind); |
| 66 | } | 66 | } |
| 67 | Ok(()) | 67 | Ok(()) |
| 68 | } | 68 | } |
| @@ -75,7 +75,7 @@ mod loose { · 6 unmodified lines | |||
| 75 | ("broken", "does not parse", true), | 75 | ("broken", "does not parse", true), |
| 76 | ("../escaping", "an invalid ref name", true), | 76 | ("../escaping", "an invalid ref name", true), |
| 77 | ] { | 77 | ] { |
| 78 | let reference = store.loose_find(*partial_name); | 78 | let reference = store.try_find_loose(*partial_name); |
| 79 | if *is_err { | 79 | if *is_err { |
| 80 | assert!(reference.is_err(), "{}", reason); | 80 | assert!(reference.is_err(), "{}", reason); |
| 81 | } else { | 81 | } else { |
| @@ -202,7 +202,7 @@ fn loose_iter_with_prefix() -> crate::Result { · 201 unmodified lines | |||
| 202 | 202 | ||
| 203 | #[test] | 203 | #[test] |
| 204 | fn overlay_iter() -> crate::Result { | 204 | fn overlay_iter() -> crate::Result { |
| 205 | use git_ref::mutable::Target::*; | 205 | use git_ref::Target::*; |
| 206 | 206 | ||
| 207 | let store = store_at("make_packed_ref_repository_for_overlay.sh")?; | 207 | let store = store_at("make_packed_ref_repository_for_overlay.sh")?; |
| 208 | let ref_names = store | 208 | let ref_names = store |
| @@ -249,7 +249,7 @@ fn overlay_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { · 40 unmodified lines | |||
| 249 | 249 | ||
| 250 | #[test] | 250 | #[test] |
| 251 | fn overlay_prefixed_iter() -> crate::Result { | 251 | fn overlay_prefixed_iter() -> crate::Result { |
| 252 | use git_ref::mutable::Target::*; | 252 | use git_ref::Target::*; |
| 253 | 253 | ||
| 254 | let store = store_at("make_packed_ref_repository_for_overlay.sh")?; | 254 | let store = store_at("make_packed_ref_repository_for_overlay.sh")?; |
| 255 | let ref_names = store | 255 | let ref_names = store |
| @@ -1,15 +1,16 @@ | |||
| 1 | mod prepare_and_commit { | 1 | mod prepare_and_commit { |
| 2 | use bstr::BString; | 2 | use bstr::BString; |
| 3 | |||
| 3 | use git_actor::{Sign, Time}; | 4 | use git_actor::{Sign, Time}; |
| 4 | use git_hash::ObjectId; | 5 | use git_hash::ObjectId; |
| 5 | use git_ref::{file, file::log}; | 6 | use git_ref::file; |
| 6 | 7 | ||
| 7 | fn reflog_lines(store: &file::Store, name: &str) -> crate::Result<Vec<log::mutable::Line>> { | 8 | fn reflog_lines(store: &file::Store, name: &str) -> crate::Result<Vec<file::log::Line>> { |
| 8 | let mut buf = Vec::new(); | 9 | let mut buf = Vec::new(); |
| 9 | let res = store | 10 | let res = store |
| 10 | .reflog_iter(name, &mut buf)? | 11 | .reflog_iter(name, &mut buf)? |
| 11 | .expect("existing reflog") | 12 | .expect("existing reflog") |
| 12 | .map(|l| l.map(log::mutable::Line::from)) | 13 | .map(|l| l.map(file::log::Line::from)) |
| 13 | .collect::<std::result::Result<Vec<_>, _>>()?; | 14 | .collect::<std::result::Result<Vec<_>, _>>()?; |
| 14 | Ok(res) | 15 | Ok(res) |
| 15 | } | 16 | } |
| @@ -32,8 +33,8 @@ mod prepare_and_commit { · 16 unmodified lines | |||
| 32 | } | 33 | } |
| 33 | } | 34 | } |
| 34 | 35 | ||
| 35 | fn log_line(previous: ObjectId, new: ObjectId, message: impl Into<BString>) -> log::mutable::Line { | 36 | fn log_line(previous: ObjectId, new: ObjectId, message: impl Into<BString>) -> file::log::Line { |
| 36 | log::mutable::Line { | 37 | file::log::Line { |
| 37 | previous_oid: previous, | 38 | previous_oid: previous, |
| 38 | new_oid: new, | 39 | new_oid: new, |
| 39 | signature: committer(), | 40 | signature: committer(), |
| @@ -11,8 +11,8 @@ use git_ref::{ · 10 unmodified lines | |||
| 11 | transaction::{self, PackedRefs}, | 11 | transaction::{self, PackedRefs}, |
| 12 | WriteReflog, | 12 | WriteReflog, |
| 13 | }, | 13 | }, |
| 14 | mutable::Target, | ||
| 15 | transaction::{Change, Create, LogChange, RefEdit, RefLog}, | 14 | transaction::{Change, Create, LogChange, RefEdit, RefLog}, |
| 15 | Target, | ||
| 16 | }; | 16 | }; |
| 17 | use git_testtools::hex_to_id; | 17 | use git_testtools::hex_to_id; |
| 18 | use std::convert::TryInto; | 18 | use std::convert::TryInto; |
| @@ -46,7 +46,7 @@ fn reference_with_equally_named_empty_or_non_empty_directory_already_in_place_ca · 27 unmodified lines | |||
| 46 | if *is_empty { | 46 | if *is_empty { |
| 47 | let edits = edits?; | 47 | let edits = edits?; |
| 48 | assert!( | 48 | assert!( |
| 49 | store.loose_find(edits[0].name.to_partial())?.is_some(), | 49 | store.try_find_loose(edits[0].name.to_partial())?.is_some(), |
| 50 | "HEAD was created despite a directory being in the way" | 50 | "HEAD was created despite a directory being in the way" |
| 51 | ); | 51 | ); |
| 52 | } else { | 52 | } else { |
| @@ -96,7 +96,7 @@ fn reference_with_old_value_must_exist_when_creating_it() -> crate::Result { · 43 unmodified lines | |||
| 96 | #[test] | 96 | #[test] |
| 97 | fn reference_with_explicit_value_must_match_the_value_on_update() -> crate::Result { | 97 | fn reference_with_explicit_value_must_match_the_value_on_update() -> crate::Result { |
| 98 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; | 98 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 99 | let head = store.loose_find("HEAD")?.expect("head exists already"); | 99 | let head = store.try_find_loose("HEAD")?.expect("head exists already"); |
| 100 | let target = head.target; | 100 | let target = head.target; |
| 101 | 101 | ||
| 102 | let res = store.transaction().prepare( | 102 | let res = store.transaction().prepare( |
| @@ -126,7 +126,7 @@ fn reference_with_explicit_value_must_match_the_value_on_update() -> crate::Resu · 23 unmodified lines | |||
| 126 | #[test] | 126 | #[test] |
| 127 | fn reference_with_create_only_must_not_exist_already_when_creating_it_if_the_value_does_not_match() -> crate::Result { | 127 | fn reference_with_create_only_must_not_exist_already_when_creating_it_if_the_value_does_not_match() -> crate::Result { |
| 128 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; | 128 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 129 | let head = store.loose_find("HEAD")?.expect("head exists already"); | 129 | let head = store.try_find_loose("HEAD")?.expect("head exists already"); |
| 130 | let target = head.target; | 130 | let target = head.target; |
| 131 | 131 | ||
| 132 | let res = store.transaction().prepare( | 132 | let res = store.transaction().prepare( |
| @@ -211,7 +211,7 @@ fn namespaced_updates_or_deletions_cause_reference_names_to_be_rewritten_and_obs · 78 unmodified lines | |||
| 211 | #[test] | 211 | #[test] |
| 212 | fn reference_with_create_only_must_not_exist_already_when_creating_it_unless_the_value_matches() -> crate::Result { | 212 | fn reference_with_create_only_must_not_exist_already_when_creating_it_unless_the_value_matches() -> crate::Result { |
| 213 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; | 213 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 214 | let head = store.loose_find("HEAD")?.expect("head exists already"); | 214 | let head = store.try_find_loose("HEAD")?.expect("head exists already"); |
| 215 | let target = head.target; | 215 | let target = head.target; |
| 216 | let previous_reflog_count = reflog_lines(&store, "HEAD")?.len(); | 216 | let previous_reflog_count = reflog_lines(&store, "HEAD")?.len(); |
| 217 | 217 | ||
| @@ -289,7 +289,10 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { · 71 unmodified lines | |||
| 289 | let (_keep, mut store) = empty_store()?; | 289 | let (_keep, mut store) = empty_store()?; |
| 290 | store.write_reflog = *reflog_writemode; | 290 | store.write_reflog = *reflog_writemode; |
| 291 | let referent = "refs/heads/alt-main"; | 291 | let referent = "refs/heads/alt-main"; |
| 292 | assert!(store.loose_find(referent)?.is_none(), "the reference does not exist"); | 292 | assert!( |
| 293 | store.try_find_loose(referent)?.is_none(), | ||
| 294 | "the reference does not exist" | ||
| 295 | ); | ||
| 293 | let log_ignored = LogChange { | 296 | let log_ignored = LogChange { |
| 294 | mode: RefLog::AndReference, | 297 | mode: RefLog::AndReference, |
| 295 | force_create_reflog: false, | 298 | force_create_reflog: false, |
| @@ -325,12 +328,12 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { · 29 unmodified lines | |||
| 325 | "no split was performed" | 328 | "no split was performed" |
| 326 | ); | 329 | ); |
| 327 | 330 | ||
| 328 | let head = store.loose_find_existing(edits[0].name.to_partial())?; | 331 | let head = store.find_loose(edits[0].name.to_partial())?; |
| 329 | assert_eq!(head.name.as_bstr(), "HEAD"); | 332 | assert_eq!(head.name.as_bstr(), "HEAD"); |
| 330 | assert_eq!(head.kind(), git_ref::Kind::Symbolic); | 333 | assert_eq!(head.kind(), git_ref::Kind::Symbolic); |
| 331 | assert_eq!(head.target.borrow().as_name(), Some(referent.as_bytes().as_bstr())); | 334 | assert_eq!(head.target.to_ref().as_name(), Some(referent.as_bytes().as_bstr())); |
| 332 | assert!(!head.log_exists(&store), "no reflog is written for symbolic ref"); | 335 | assert!(!head.log_exists(&store), "no reflog is written for symbolic ref"); |
| 333 | assert!(store.loose_find(referent)?.is_none(), "referent wasn't created"); | 336 | assert!(store.try_find_loose(referent)?.is_none(), "referent wasn't created"); |
| 334 | 337 | ||
| 335 | let new_oid = hex_to_id("28ce6a8b26aa170e1de65536fe8abe1832bd3242"); | 338 | let new_oid = hex_to_id("28ce6a8b26aa170e1de65536fe8abe1832bd3242"); |
| 336 | let new = Target::Peeled(new_oid); | 339 | let new = Target::Peeled(new_oid); |
| @@ -386,22 +389,22 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { · 49 unmodified lines | |||
| 386 | ] | 389 | ] |
| 387 | ); | 390 | ); |
| 388 | 391 | ||
| 389 | let head = store.loose_find_existing("HEAD")?; | 392 | let head = store.find_loose("HEAD")?; |
| 390 | assert_eq!( | 393 | assert_eq!( |
| 391 | head.kind(), | 394 | head.kind(), |
| 392 | git_ref::Kind::Symbolic, | 395 | git_ref::Kind::Symbolic, |
| 393 | "head is still symbolic, not detached" | 396 | "head is still symbolic, not detached" |
| 394 | ); | 397 | ); |
| 395 | assert_eq!( | 398 | assert_eq!( |
| 396 | head.target.borrow().as_name(), | 399 | head.target.to_ref().as_name(), |
| 397 | Some(referent.as_bytes().as_bstr()), | 400 | Some(referent.as_bytes().as_bstr()), |
| 398 | "it still points to the referent" | 401 | "it still points to the referent" |
| 399 | ); | 402 | ); |
| 400 | 403 | ||
| 401 | let referent_ref = store.loose_find_existing(referent)?; | 404 | let referent_ref = store.find_loose(referent)?; |
| 402 | assert_eq!(referent_ref.kind(), git_ref::Kind::Peeled, "referent is a peeled ref"); | 405 | assert_eq!(referent_ref.kind(), git_ref::Kind::Peeled, "referent is a peeled ref"); |
| 403 | assert_eq!( | 406 | assert_eq!( |
| 404 | referent_ref.target.borrow().as_id(), | 407 | referent_ref.target.to_ref().as_id(), |
| 405 | Some(new_oid.as_ref()), | 408 | Some(new_oid.as_ref()), |
| 406 | "referent points to desired hash" | 409 | "referent points to desired hash" |
| 407 | ); | 410 | ); |
| @@ -430,8 +433,8 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { · 22 unmodified lines | |||
| 430 | /// be needed to keep the reflog consistent | 433 | /// be needed to keep the reflog consistent |
| 431 | fn write_reference_to_which_head_points_to_does_not_update_heads_reflog_even_though_it_should() -> crate::Result { | 434 | fn write_reference_to_which_head_points_to_does_not_update_heads_reflog_even_though_it_should() -> crate::Result { |
| 432 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; | 435 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 433 | let head = store.loose_find_existing("HEAD")?; | 436 | let head = store.find_loose("HEAD")?; |
| 434 | let referent = head.target.borrow().as_name().expect("symbolic ref").to_owned(); | 437 | let referent = head.target.to_ref().as_name().expect("symbolic ref").to_owned(); |
| 435 | let previous_head_reflog = reflog_lines(&store, "HEAD")?; | 438 | let previous_head_reflog = reflog_lines(&store, "HEAD")?; |
| 436 | 439 | ||
| 437 | let new_id = hex_to_id("01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc"); | 440 | let new_id = hex_to_id("01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc"); |
| @@ -497,7 +500,7 @@ fn write_reference_to_which_head_points_to_does_not_update_heads_reflog_even_tho · 59 unmodified lines | |||
| 497 | fn packed_refs_are_looked_up_when_checking_existing_values() -> crate::Result { | 500 | fn packed_refs_are_looked_up_when_checking_existing_values() -> crate::Result { |
| 498 | let (_keep, store) = store_writable("make_packed_ref_repository.sh")?; | 501 | let (_keep, store) = store_writable("make_packed_ref_repository.sh")?; |
| 499 | assert!( | 502 | assert!( |
| 500 | store.loose_find("main")?.is_none(), | 503 | store.try_find_loose("main")?.is_none(), |
| 501 | "no loose main available, it's packed" | 504 | "no loose main available, it's packed" |
| 502 | ); | 505 | ); |
| 503 | let new_id = hex_to_id("0000000000000000000000000000000000000001"); | 506 | let new_id = hex_to_id("0000000000000000000000000000000000000001"); |
| @@ -528,12 +531,12 @@ fn packed_refs_are_looked_up_when_checking_existing_values() -> crate::Result { · 24 unmodified lines | |||
| 528 | 531 | ||
| 529 | let packed = store.packed_buffer().unwrap().expect("packed refs is available"); | 532 | let packed = store.packed_buffer().unwrap().expect("packed refs is available"); |
| 530 | assert_eq!( | 533 | assert_eq!( |
| 531 | packed.find_existing("main")?.target(), | 534 | packed.find("main")?.target(), |
| 532 | old_id, | 535 | old_id, |
| 533 | "packed refs aren't rewritten, the change goes into the loose ref instead which shadows packed refs of same name" | 536 | "packed refs aren't rewritten, the change goes into the loose ref instead which shadows packed refs of same name" |
| 534 | ); | 537 | ); |
| 535 | assert_eq!( | 538 | assert_eq!( |
| 536 | store.loose_find_existing("main")?.target.as_id(), | 539 | store.find_loose("main")?.target.as_id(), |
| 537 | Some(new_id.as_ref()), | 540 | Some(new_id.as_ref()), |
| 538 | "the new id was written to the loose ref" | 541 | "the new id was written to the loose ref" |
| 539 | ); | 542 | ); |
| @@ -608,10 +611,10 @@ fn packed_refs_creation_with_packed_refs_mode_prune_removes_original_loose_refs( · 68 unmodified lines | |||
| 608 | #[test] | 611 | #[test] |
| 609 | fn packed_refs_creation_with_packed_refs_mode_leave_keeps_original_loose_refs() -> crate::Result { | 612 | fn packed_refs_creation_with_packed_refs_mode_leave_keeps_original_loose_refs() -> crate::Result { |
| 610 | let (_keep, store) = store_writable("make_packed_ref_repository_for_overlay.sh")?; | 613 | let (_keep, store) = store_writable("make_packed_ref_repository_for_overlay.sh")?; |
| 611 | let branch = store.find_existing("newer-as-loose", None)?; | 614 | let branch = store.find("newer-as-loose", None)?; |
| 612 | let packed = store.packed_buffer()?.expect("packed-refs"); | 615 | let packed = store.packed_buffer()?.expect("packed-refs"); |
| 613 | assert_ne!( | 616 | assert_ne!( |
| 614 | packed.find_existing("newer-as-loose")?.target(), | 617 | packed.find("newer-as-loose")?.target(), |
| 615 | branch.target().as_id().expect("peeled"), | 618 | branch.target().as_id().expect("peeled"), |
| 616 | "the packed ref is outdated" | 619 | "the packed ref is outdated" |
| 617 | ); | 620 | ); |
| @@ -662,12 +665,8 @@ fn packed_refs_creation_with_packed_refs_mode_leave_keeps_original_loose_refs() · 44 unmodified lines | |||
| 662 | "the amount of packed refs doesn't change" | 665 | "the amount of packed refs doesn't change" |
| 663 | ); | 666 | ); |
| 664 | assert_eq!( | 667 | assert_eq!( |
| 665 | packed.find_existing("newer-as-loose")?.target(), | 668 | packed.find("newer-as-loose")?.target(), |
| 666 | store | 669 | store.find("newer-as-loose", None)?.target().as_id().expect("peeled"), |
| 667 | .find_existing("newer-as-loose", None)? | ||
| 668 | .target() | ||
| 669 | .as_id() | ||
| 670 | .expect("peeled"), | ||
| 671 | "the packed ref is now up to date and the loose ref definitely still exists" | 670 | "the packed ref is now up to date and the loose ref definitely still exists" |
| 672 | ); | 671 | ); |
| 673 | Ok(()) | 672 | Ok(()) |
| @@ -4,8 +4,8 @@ use crate::file::{ · 3 unmodified lines | |||
| 4 | }; | 4 | }; |
| 5 | use git_lock::acquire::Fail; | 5 | use git_lock::acquire::Fail; |
| 6 | use git_ref::{ | 6 | use git_ref::{ |
| 7 | mutable::Target, | ||
| 8 | transaction::{Change, RefEdit, RefLog}, | 7 | transaction::{Change, RefEdit, RefLog}, |
| 8 | Target, | ||
| 9 | }; | 9 | }; |
| 10 | use git_testtools::hex_to_id; | 10 | use git_testtools::hex_to_id; |
| 11 | use std::convert::TryInto; | 11 | use std::convert::TryInto; |
| @@ -58,9 +58,9 @@ fn delete_a_ref_which_is_gone_but_must_exist_fails() -> crate::Result { · 46 unmodified lines | |||
| 58 | #[test] | 58 | #[test] |
| 59 | fn delete_ref_and_reflog_on_symbolic_no_deref() -> crate::Result { | 59 | fn delete_ref_and_reflog_on_symbolic_no_deref() -> crate::Result { |
| 60 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; | 60 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 61 | let head = store.loose_find_existing("HEAD")?; | 61 | let head = store.find_loose("HEAD")?; |
| 62 | assert!(head.log_exists(&store)); | 62 | assert!(head.log_exists(&store)); |
| 63 | let _main = store.loose_find_existing("main")?; | 63 | let _main = store.find_loose("main")?; |
| 64 | 64 | ||
| 65 | let edits = store | 65 | let edits = store |
| 66 | .transaction() | 66 | .transaction() |
| @@ -93,15 +93,15 @@ fn delete_ref_and_reflog_on_symbolic_no_deref() -> crate::Result { · 26 unmodified lines | |||
| 93 | store.reflog_iter_rev("HEAD", &mut [0u8; 128])?.is_none(), | 93 | store.reflog_iter_rev("HEAD", &mut [0u8; 128])?.is_none(), |
| 94 | "reflog was deleted" | 94 | "reflog was deleted" |
| 95 | ); | 95 | ); |
| 96 | assert!(store.loose_find("HEAD")?.is_none(), "ref was deleted"); | 96 | assert!(store.try_find_loose("HEAD")?.is_none(), "ref was deleted"); |
| 97 | assert!(store.loose_find("main")?.is_some(), "referent still exists"); | 97 | assert!(store.try_find_loose("main")?.is_some(), "referent still exists"); |
| 98 | Ok(()) | 98 | Ok(()) |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | #[test] | 101 | #[test] |
| 102 | fn delete_ref_with_incorrect_previous_value_fails() -> crate::Result { | 102 | fn delete_ref_with_incorrect_previous_value_fails() -> crate::Result { |
| 103 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; | 103 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 104 | let head = store.loose_find_existing("HEAD")?; | 104 | let head = store.find_loose("HEAD")?; |
| 105 | assert!(head.log_exists(&store)); | 105 | assert!(head.log_exists(&store)); |
| 106 | 106 | ||
| 107 | let res = store.transaction().prepare( | 107 | let res = store.transaction().prepare( |
| @@ -123,9 +123,9 @@ fn delete_ref_with_incorrect_previous_value_fails() -> crate::Result { · 15 unmodified lines | |||
| 123 | Ok(_) => unreachable!("must be err"), | 123 | Ok(_) => unreachable!("must be err"), |
| 124 | } | 124 | } |
| 125 | // everything stays as is | 125 | // everything stays as is |
| 126 | let head = store.loose_find_existing("HEAD")?; | 126 | let head = store.find_loose("HEAD")?; |
| 127 | assert!(head.log_exists(&store)); | 127 | assert!(head.log_exists(&store)); |
| 128 | let main = store.loose_find_existing("main").expect("referent still exists"); | 128 | let main = store.find_loose("main").expect("referent still exists"); |
| 129 | assert!(main.log_exists(&store)); | 129 | assert!(main.log_exists(&store)); |
| 130 | Ok(()) | 130 | Ok(()) |
| 131 | } | 131 | } |
| @@ -133,7 +133,7 @@ fn delete_ref_with_incorrect_previous_value_fails() -> crate::Result { · 1 unmodified line | |||
| 133 | #[test] | 133 | #[test] |
| 134 | fn delete_reflog_only_of_symbolic_no_deref() -> crate::Result { | 134 | fn delete_reflog_only_of_symbolic_no_deref() -> crate::Result { |
| 135 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; | 135 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 136 | let head = store.loose_find_existing("HEAD")?; | 136 | let head = store.find_loose("HEAD")?; |
| 137 | assert!(head.log_exists(&store)); | 137 | assert!(head.log_exists(&store)); |
| 138 | 138 | ||
| 139 | let edits = store | 139 | let edits = store |
| @@ -152,9 +152,9 @@ fn delete_reflog_only_of_symbolic_no_deref() -> crate::Result { · 12 unmodified lines | |||
| 152 | .commit(&committer())?; | 152 | .commit(&committer())?; |
| 153 | 153 | ||
| 154 | assert_eq!(edits.len(), 1); | 154 | assert_eq!(edits.len(), 1); |
| 155 | let head = store.loose_find_existing("HEAD")?; | 155 | let head = store.find_loose("HEAD")?; |
| 156 | assert!(!head.log_exists(&store)); | 156 | assert!(!head.log_exists(&store)); |
| 157 | let main = store.loose_find_existing("main").expect("referent still exists"); | 157 | let main = store.find_loose("main").expect("referent still exists"); |
| 158 | assert!(main.log_exists(&store), "log is untouched, too"); | 158 | assert!(main.log_exists(&store), "log is untouched, too"); |
| 159 | assert_eq!( | 159 | assert_eq!( |
| 160 | main.target, | 160 | main.target, |
| @@ -167,7 +167,7 @@ fn delete_reflog_only_of_symbolic_no_deref() -> crate::Result { · 6 unmodified lines | |||
| 167 | #[test] | 167 | #[test] |
| 168 | fn delete_reflog_only_of_symbolic_with_deref() -> crate::Result { | 168 | fn delete_reflog_only_of_symbolic_with_deref() -> crate::Result { |
| 169 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; | 169 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 170 | let head = store.loose_find_existing("HEAD")?; | 170 | let head = store.find_loose("HEAD")?; |
| 171 | assert!(head.log_exists(&store)); | 171 | assert!(head.log_exists(&store)); |
| 172 | 172 | ||
| 173 | let edits = store | 173 | let edits = store |
| @@ -186,9 +186,9 @@ fn delete_reflog_only_of_symbolic_with_deref() -> crate::Result { · 12 unmodified lines | |||
| 186 | .commit(&committer())?; | 186 | .commit(&committer())?; |
| 187 | 187 | ||
| 188 | assert_eq!(edits.len(), 2); | 188 | assert_eq!(edits.len(), 2); |
| 189 | let head = store.loose_find_existing("HEAD")?; | 189 | let head = store.find_loose("HEAD")?; |
| 190 | assert!(!head.log_exists(&store)); | 190 | assert!(!head.log_exists(&store)); |
| 191 | let main = store.loose_find_existing("main").expect("referent still exists"); | 191 | let main = store.find_loose("main").expect("referent still exists"); |
| 192 | assert!(!main.log_exists(&store), "log is removed"); | 192 | assert!(!main.log_exists(&store), "log is removed"); |
| 193 | assert_eq!( | 193 | assert_eq!( |
| 194 | main.target, | 194 | main.target, |
| @@ -203,7 +203,7 @@ fn delete_reflog_only_of_symbolic_with_deref() -> crate::Result { · 8 unmodified lines | |||
| 203 | fn delete_broken_ref_that_must_exist_fails_as_it_is_no_valid_ref() -> crate::Result { | 203 | fn delete_broken_ref_that_must_exist_fails_as_it_is_no_valid_ref() -> crate::Result { |
| 204 | let (_keep, store) = empty_store()?; | 204 | let (_keep, store) = empty_store()?; |
| 205 | std::fs::write(store.base.join("HEAD"), &b"broken")?; | 205 | std::fs::write(store.base.join("HEAD"), &b"broken")?; |
| 206 | assert!(store.loose_find("HEAD").is_err(), "the ref is truly broken"); | 206 | assert!(store.try_find_loose("HEAD").is_err(), "the ref is truly broken"); |
| 207 | 207 | ||
| 208 | let res = store.transaction().prepare( | 208 | let res = store.transaction().prepare( |
| 209 | Some(RefEdit { | 209 | Some(RefEdit { |
| @@ -233,7 +233,7 @@ fn delete_broken_ref_that_must_exist_fails_as_it_is_no_valid_ref() -> crate::Res · 23 unmodified lines | |||
| 233 | fn delete_broken_ref_that_may_not_exist_works_even_in_deref_mode() -> crate::Result { | 233 | fn delete_broken_ref_that_may_not_exist_works_even_in_deref_mode() -> crate::Result { |
| 234 | let (_keep, store) = empty_store()?; | 234 | let (_keep, store) = empty_store()?; |
| 235 | std::fs::write(store.base.join("HEAD"), &b"broken")?; | 235 | std::fs::write(store.base.join("HEAD"), &b"broken")?; |
| 236 | assert!(store.loose_find("HEAD").is_err(), "the ref is truly broken"); | 236 | assert!(store.try_find_loose("HEAD").is_err(), "the ref is truly broken"); |
| 237 | 237 | ||
| 238 | let edits = store | 238 | let edits = store |
| 239 | .transaction() | 239 | .transaction() |
| @@ -250,7 +250,7 @@ fn delete_broken_ref_that_may_not_exist_works_even_in_deref_mode() -> crate::Res · 10 unmodified lines | |||
| 250 | )? | 250 | )? |
| 251 | .commit(&committer())?; | 251 | .commit(&committer())?; |
| 252 | 252 | ||
| 253 | assert!(store.loose_find("HEAD")?.is_none(), "the ref was deleted"); | 253 | assert!(store.try_find_loose("HEAD")?.is_none(), "the ref was deleted"); |
| 254 | assert_eq!( | 254 | assert_eq!( |
| 255 | edits, | 255 | edits, |
| 256 | vec![RefEdit { | 256 | vec![RefEdit { |
| @@ -270,7 +270,7 @@ fn store_write_mode_has_no_effect_and_reflogs_are_always_deleted() -> crate::Res · 13 unmodified lines | |||
| 270 | for reflog_writemode in &[git_ref::file::WriteReflog::Normal, git_ref::file::WriteReflog::Disable] { | 270 | for reflog_writemode in &[git_ref::file::WriteReflog::Normal, git_ref::file::WriteReflog::Disable] { |
| 271 | let (_keep, mut store) = store_writable("make_repo_for_reflog.sh")?; | 271 | let (_keep, mut store) = store_writable("make_repo_for_reflog.sh")?; |
| 272 | store.write_reflog = *reflog_writemode; | 272 | store.write_reflog = *reflog_writemode; |
| 273 | assert!(store.loose_find_existing("HEAD")?.log_exists(&store)); | 273 | assert!(store.find_loose("HEAD")?.log_exists(&store)); |
| 274 | assert!(store.packed_buffer()?.is_none(), "there is no pack"); | 274 | assert!(store.packed_buffer()?.is_none(), "there is no pack"); |
| 275 | 275 | ||
| 276 | let edits = store | 276 | let edits = store |
| @@ -288,10 +288,7 @@ fn store_write_mode_has_no_effect_and_reflogs_are_always_deleted() -> crate::Res · 11 unmodified lines | |||
| 288 | )? | 288 | )? |
| 289 | .commit(&committer())?; | 289 | .commit(&committer())?; |
| 290 | assert_eq!(edits.len(), 1); | 290 | assert_eq!(edits.len(), 1); |
| 291 | assert!( | 291 | assert!(!store.find_loose("HEAD")?.log_exists(&store), "log was deleted"); |
| 292 | !store.loose_find_existing("HEAD")?.log_exists(&store), | ||
| 293 | "log was deleted" | ||
| 294 | ); | ||
| 295 | assert!(store.packed_buffer()?.is_none(), "there still is no pack"); | 292 | assert!(store.packed_buffer()?.is_none(), "there still is no pack"); |
| 296 | } | 293 | } |
| 297 | Ok(()) | 294 | Ok(()) |
| @@ -302,11 +299,11 @@ fn packed_refs_are_consulted_when_determining_previous_value_of_ref_to_be_delete · 4 unmodified lines | |||
| 302 | ) -> crate::Result { | 299 | ) -> crate::Result { |
| 303 | let (_keep, store) = store_writable("make_packed_ref_repository.sh")?; | 300 | let (_keep, store) = store_writable("make_packed_ref_repository.sh")?; |
| 304 | assert!( | 301 | assert!( |
| 305 | store.loose_find("main")?.is_none(), | 302 | store.try_find_loose("main")?.is_none(), |
| 306 | "no loose main available, it's packed" | 303 | "no loose main available, it's packed" |
| 307 | ); | 304 | ); |
| 308 | assert!( | 305 | assert!( |
| 309 | store.packed_buffer()?.expect("packed").find("main")?.is_some(), | 306 | store.packed_buffer()?.expect("packed").try_find("main")?.is_some(), |
| 310 | "packed main is available" | 307 | "packed main is available" |
| 311 | ); | 308 | ); |
| 312 | 309 | ||
| @@ -328,7 +325,7 @@ fn packed_refs_are_consulted_when_determining_previous_value_of_ref_to_be_delete · 15 unmodified lines | |||
| 328 | 325 | ||
| 329 | assert_eq!(edits.len(), 1, "an edit was performed in the packed refs store"); | 326 | assert_eq!(edits.len(), 1, "an edit was performed in the packed refs store"); |
| 330 | let packed = store.packed_buffer()?.expect("packed ref present"); | 327 | let packed = store.packed_buffer()?.expect("packed ref present"); |
| 331 | assert!(packed.find("main")?.is_none(), "no main present after deletion"); | 328 | assert!(packed.try_find("main")?.is_none(), "no main present after deletion"); |
| 332 | Ok(()) | 329 | Ok(()) |
| 333 | } | 330 | } |
| 334 | 331 | ||
| @@ -336,10 +333,10 @@ fn packed_refs_are_consulted_when_determining_previous_value_of_ref_to_be_delete · 1 unmodified line | |||
| 336 | fn a_loose_ref_with_old_value_check_and_outdated_packed_refs_value_deletes_both_refs() -> crate::Result { | 333 | fn a_loose_ref_with_old_value_check_and_outdated_packed_refs_value_deletes_both_refs() -> crate::Result { |
| 337 | let (_keep, store) = store_writable("make_packed_ref_repository_for_overlay.sh")?; | 334 | let (_keep, store) = store_writable("make_packed_ref_repository_for_overlay.sh")?; |
| 338 | let packed = store.packed_buffer()?.expect("packed-refs"); | 335 | let packed = store.packed_buffer()?.expect("packed-refs"); |
| 339 | let branch = store.find_existing("newer-as-loose", Some(&packed))?; | 336 | let branch = store.find("newer-as-loose", Some(&packed))?; |
| 340 | let branch_id = branch.target().as_id().map(ToOwned::to_owned).expect("peeled"); | 337 | let branch_id = branch.target().as_id().map(ToOwned::to_owned).expect("peeled"); |
| 341 | assert_ne!( | 338 | assert_ne!( |
| 342 | packed.find_existing("newer-as-loose")?.target(), | 339 | packed.find("newer-as-loose")?.target(), |
| 343 | branch_id, | 340 | branch_id, |
| 344 | "the packed ref is outdated" | 341 | "the packed ref is outdated" |
| 345 | ); | 342 | ); |
| @@ -365,7 +362,9 @@ fn a_loose_ref_with_old_value_check_and_outdated_packed_refs_value_deletes_both_ · 19 unmodified lines | |||
| 365 | "only one edit even though technically two places were changed" | 362 | "only one edit even though technically two places were changed" |
| 366 | ); | 363 | ); |
| 367 | assert!( | 364 | assert!( |
| 368 | store.find("newer-as-loose", store.packed_buffer()?.as_ref())?.is_none(), | 365 | store |
| 366 | .try_find("newer-as-loose", store.packed_buffer()?.as_ref())? | ||
| 367 | .is_none(), | ||
| 369 | "reference is deleted everywhere" | 368 | "reference is deleted everywhere" |
| 370 | ); | 369 | ); |
| 371 | Ok(()) | 370 | Ok(()) |
| @@ -407,7 +406,10 @@ fn all_contained_references_deletes_the_packed_ref_file_too() { · 35 unmodified lines | |||
| 407 | assert!(packed.is_none(), "it won't make up packed refs"); | 406 | assert!(packed.is_none(), "it won't make up packed refs"); |
| 408 | for edit in edits { | 407 | for edit in edits { |
| 409 | assert!( | 408 | assert!( |
| 410 | store.find(edit.name.to_partial(), packed.as_ref()).unwrap().is_none(), | 409 | store |
| 410 | .try_find(edit.name.to_partial(), packed.as_ref()) | ||
| 411 | .unwrap() | ||
| 412 | .is_none(), | ||
| 411 | "delete ref cannot be found" | 413 | "delete ref cannot be found" |
| 412 | ); | 414 | ); |
| 413 | } | 415 | } |
| @@ -1,6 +1,6 @@ | |||
| 1 | use std::convert::{TryFrom, TryInto}; | 1 | use std::convert::{TryFrom, TryInto}; |
| 2 | 2 | ||
| 3 | use git_ref::{packed, PartialName}; | 3 | use git_ref::{packed, PartialNameRef}; |
| 4 | use git_testtools::fixture_path; | 4 | use git_testtools::fixture_path; |
| 5 | 5 | ||
| 6 | use crate::{ | 6 | use crate::{ |
| @@ -11,7 +11,7 @@ use crate::{ · 4 unmodified lines | |||
| 11 | #[test] | 11 | #[test] |
| 12 | fn a_lock_file_would_not_be_a_valid_partial_name() { | 12 | fn a_lock_file_would_not_be_a_valid_partial_name() { |
| 13 | // doesn't really belong here but want to make sure refname validation works as expected. | 13 | // doesn't really belong here but want to make sure refname validation works as expected. |
| 14 | let err = PartialName::try_from("heads/hello.lock").expect_err("this should fail"); | 14 | let err = PartialNameRef::try_from("heads/hello.lock").expect_err("this should fail"); |
| 15 | assert_eq!(err.to_string(), "A reference must be a valid tag name as well"); | 15 | assert_eq!(err.to_string(), "A reference must be a valid tag name as well"); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| @@ -22,9 +22,9 @@ fn all_iterable_refs_can_be_found() -> crate::Result { · 4 unmodified lines | |||
| 22 | 22 | ||
| 23 | for reference in packed_refs.iter()? { | 23 | for reference in packed_refs.iter()? { |
| 24 | let reference = reference?; | 24 | let reference = reference?; |
| 25 | let found = packed_refs.find(reference.name)?.expect("reference exists"); | 25 | let found = packed_refs.try_find(reference.name)?.expect("reference exists"); |
| 26 | assert_eq!(reference, found, "both refs are exactly the same"); | 26 | assert_eq!(reference, found, "both refs are exactly the same"); |
| 27 | let found = packed_refs.find_existing(reference.name)?; | 27 | let found = packed_refs.find(reference.name)?; |
| 28 | assert_eq!(reference, found); | 28 | assert_eq!(reference, found); |
| 29 | } | 29 | } |
| 30 | Ok(()) | 30 | Ok(()) |
| @@ -33,7 +33,7 @@ fn all_iterable_refs_can_be_found() -> crate::Result { · 2 unmodified lines | |||
| 33 | #[test] | 33 | #[test] |
| 34 | fn binary_search_a_name_past_the_end_of_the_packed_refs_file() -> crate::Result { | 34 | fn binary_search_a_name_past_the_end_of_the_packed_refs_file() -> crate::Result { |
| 35 | let packed_refs = packed::Buffer::open(fixture_path("packed-refs").join("triggers-out-of-bounds"), 32)?; | 35 | let packed_refs = packed::Buffer::open(fixture_path("packed-refs").join("triggers-out-of-bounds"), 32)?; |
| 36 | assert!(packed_refs.find("v0.0.1")?.is_none()); | 36 | assert!(packed_refs.try_find("v0.0.1")?.is_none()); |
| 37 | Ok(()) | 37 | Ok(()) |
| 38 | } | 38 | } |
| 39 | 39 | ||
| @@ -49,7 +49,7 @@ c4cebba92af964f2d126be90b8a6298c4cf84d45 refs/tags/git-actor-v0.1.0 · 9 unmodified lines | |||
| 49 | let buf = packed::Buffer::open(path, 1024)?; | 49 | let buf = packed::Buffer::open(path, 1024)?; |
| 50 | let name = "refs/tags/TEST-0.0.1"; | 50 | let name = "refs/tags/TEST-0.0.1"; |
| 51 | assert_eq!( | 51 | assert_eq!( |
| 52 | buf.find(name)?.expect("reference exists"), | 52 | buf.try_find(name)?.expect("reference exists"), |
| 53 | packed::Reference { | 53 | packed::Reference { |
| 54 | name: name.try_into()?, | 54 | name: name.try_into()?, |
| 55 | target: "916840c0e2f67d370291042cb5274a597f4fa9bc".into(), | 55 | target: "916840c0e2f67d370291042cb5274a597f4fa9bc".into(), |
| @@ -58,7 +58,7 @@ c4cebba92af964f2d126be90b8a6298c4cf84d45 refs/tags/git-actor-v0.1.0 · 2 unmodified lines | |||
| 58 | ); | 58 | ); |
| 59 | let name = "refs/tags/git-actor-v0.1.0"; | 59 | let name = "refs/tags/git-actor-v0.1.0"; |
| 60 | assert_eq!( | 60 | assert_eq!( |
| 61 | buf.find(name)?.expect("reference exists"), | 61 | buf.try_find(name)?.expect("reference exists"), |
| 62 | packed::Reference { | 62 | packed::Reference { |
| 63 | name: name.try_into()?, | 63 | name: name.try_into()?, |
| 64 | target: "c4cebba92af964f2d126be90b8a6298c4cf84d45".into(), | 64 | target: "c4cebba92af964f2d126be90b8a6298c4cf84d45".into(), |
| @@ -67,7 +67,7 @@ c4cebba92af964f2d126be90b8a6298c4cf84d45 refs/tags/git-actor-v0.1.0 · 2 unmodified lines | |||
| 67 | ); | 67 | ); |
| 68 | let name = "refs/tags/git-actor-v0.1.1"; | 68 | let name = "refs/tags/git-actor-v0.1.1"; |
| 69 | assert_eq!( | 69 | assert_eq!( |
| 70 | buf.find(name)?.expect("reference exists"), | 70 | buf.try_find(name)?.expect("reference exists"), |
| 71 | packed::Reference { | 71 | packed::Reference { |
| 72 | name: name.try_into()?, | 72 | name: name.try_into()?, |
| 73 | target: "0b92c8a256ae06c189e3b9c30b646d62ac8f7d10".into(), | 73 | target: "0b92c8a256ae06c189e3b9c30b646d62ac8f7d10".into(), |
| @@ -83,50 +83,50 @@ fn partial_name_to_full_name_conversion_rules_are_applied() -> crate::Result { · 9 unmodified lines | |||
| 83 | let packed = store.packed_buffer()?.expect("packed-refs exists"); | 83 | let packed = store.packed_buffer()?.expect("packed-refs exists"); |
| 84 | 84 | ||
| 85 | assert_eq!( | 85 | assert_eq!( |
| 86 | store.loose_find_existing("origin")?.name.as_bstr(), | 86 | store.find_loose("origin")?.name.as_bstr(), |
| 87 | "refs/remotes/origin/HEAD", | 87 | "refs/remotes/origin/HEAD", |
| 88 | "a special that only applies to loose refs" | 88 | "a special that only applies to loose refs" |
| 89 | ); | 89 | ); |
| 90 | assert!( | 90 | assert!( |
| 91 | packed.find("origin")?.is_none(), | 91 | packed.try_find("origin")?.is_none(), |
| 92 | "packed refs don't have this special case as they don't store HEADs or symrefs" | 92 | "packed refs don't have this special case as they don't store HEADs or symrefs" |
| 93 | ); | 93 | ); |
| 94 | assert_eq!( | 94 | assert_eq!( |
| 95 | store.loose_find_existing("HEAD")?.name.as_bstr(), | 95 | store.find_loose("HEAD")?.name.as_bstr(), |
| 96 | "HEAD", | 96 | "HEAD", |
| 97 | "HEAD can be found in loose stores" | 97 | "HEAD can be found in loose stores" |
| 98 | ); | 98 | ); |
| 99 | assert!( | 99 | assert!( |
| 100 | packed.find("HEAD")?.is_none(), | 100 | packed.try_find("HEAD")?.is_none(), |
| 101 | "packed refs definitely don't contain HEAD" | 101 | "packed refs definitely don't contain HEAD" |
| 102 | ); | 102 | ); |
| 103 | assert_eq!( | 103 | assert_eq!( |
| 104 | packed.find("head-or-tag")?.expect("present").name.as_bstr(), | 104 | packed.try_find("head-or-tag")?.expect("present").name.as_bstr(), |
| 105 | "refs/tags/head-or-tag", | 105 | "refs/tags/head-or-tag", |
| 106 | "it finds tags first" | 106 | "it finds tags first" |
| 107 | ); | 107 | ); |
| 108 | assert_eq!( | 108 | assert_eq!( |
| 109 | packed.find("heads/head-or-tag")?.expect("present").name.as_bstr(), | 109 | packed.try_find("heads/head-or-tag")?.expect("present").name.as_bstr(), |
| 110 | "refs/heads/head-or-tag", | 110 | "refs/heads/head-or-tag", |
| 111 | "it finds heads when disambiguated" | 111 | "it finds heads when disambiguated" |
| 112 | ); | 112 | ); |
| 113 | assert_eq!( | 113 | assert_eq!( |
| 114 | packed.find("main")?.expect("present").name.as_bstr(), | 114 | packed.try_find("main")?.expect("present").name.as_bstr(), |
| 115 | "refs/heads/main", | 115 | "refs/heads/main", |
| 116 | "it finds local heads before remote ones" | 116 | "it finds local heads before remote ones" |
| 117 | ); | 117 | ); |
| 118 | assert_eq!( | 118 | assert_eq!( |
| 119 | packed.find("origin/main")?.expect("present").name.as_bstr(), | 119 | packed.try_find("origin/main")?.expect("present").name.as_bstr(), |
| 120 | "refs/remotes/origin/main", | 120 | "refs/remotes/origin/main", |
| 121 | "it finds remote heads when disambiguated" | 121 | "it finds remote heads when disambiguated" |
| 122 | ); | 122 | ); |
| 123 | assert_eq!( | 123 | assert_eq!( |
| 124 | packed.find("remotes/origin/main")?.expect("present").name.as_bstr(), | 124 | packed.try_find("remotes/origin/main")?.expect("present").name.as_bstr(), |
| 125 | "refs/remotes/origin/main", | 125 | "refs/remotes/origin/main", |
| 126 | "more specification is possible, too" | 126 | "more specification is possible, too" |
| 127 | ); | 127 | ); |
| 128 | assert_eq!( | 128 | assert_eq!( |
| 129 | packed.find("tag-object")?.expect("present"), | 129 | packed.try_find("tag-object")?.expect("present"), |
| 130 | packed::Reference { | 130 | packed::Reference { |
| 131 | name: "refs/tags/tag-object".try_into()?, | 131 | name: "refs/tags/tag-object".try_into()?, |
| 132 | target: "b3109a7e51fc593f85b145a76c70ddd1d133fafd".into(), | 132 | target: "b3109a7e51fc593f85b145a76c70ddd1d133fafd".into(), |
| @@ -150,7 +150,7 @@ bogus refs/tags/git-actor-v0.1.0 · 17 unmodified lines | |||
| 150 | 150 | ||
| 151 | let name = "refs/tags/git-actor-v0.1.1"; | 151 | let name = "refs/tags/git-actor-v0.1.1"; |
| 152 | assert_eq!( | 152 | assert_eq!( |
| 153 | buf.find(name)?.expect("reference exists"), | 153 | buf.try_find(name)?.expect("reference exists"), |
| 154 | packed::Reference { | 154 | packed::Reference { |
| 155 | name: name.try_into()?, | 155 | name: name.try_into()?, |
| 156 | target: "0b92c8a256ae06c189e3b9c30b646d62ac8f7d10".into(), | 156 | target: "0b92c8a256ae06c189e3b9c30b646d62ac8f7d10".into(), |
| @@ -160,7 +160,7 @@ bogus refs/tags/git-actor-v0.1.0 · 3 unmodified lines | |||
| 160 | 160 | ||
| 161 | for failing_name in &["refs/tags/TEST-0.0.1", "refs/tags/git-actor-v0.1.0"] { | 161 | for failing_name in &["refs/tags/TEST-0.0.1", "refs/tags/git-actor-v0.1.0"] { |
| 162 | assert_eq!( | 162 | assert_eq!( |
| 163 | buf.find(*failing_name) | 163 | buf.try_find(*failing_name) |
| 164 | .expect_err("it should detect an err") | 164 | .expect_err("it should detect an err") |
| 165 | .to_string(), | 165 | .to_string(), |
| 166 | "The reference could not be parsed" | 166 | "The reference could not be parsed" |
| @@ -178,7 +178,11 @@ fn find_speed() -> crate::Result { · 11 unmodified lines | |||
| 178 | for r in packed.iter()?.take(10_000) { | 178 | for r in packed.iter()?.take(10_000) { |
| 179 | num_refs += 1; | 179 | num_refs += 1; |
| 180 | let r = r?; | 180 | let r = r?; |
| 181 | assert_eq!(packed.find(r.name)?.expect("ref was found"), r, "the refs are the same"); | 181 | assert_eq!( |
| 182 | packed.try_find(r.name)?.expect("ref was found"), | ||
| 183 | r, | ||
| 184 | "the refs are the same" | ||
| 185 | ); | ||
| 182 | } | 186 | } |
| 183 | let elapsed = start.elapsed().as_secs_f32(); | 187 | let elapsed = start.elapsed().as_secs_f32(); |
| 184 | eprintln!( | 188 | eprintln!( |
| @@ -27,7 +27,7 @@ fn unsorted_buffers_or_those_without_a_header_can_be_opened_and_searched() { · 26 unmodified lines | |||
| 27 | .unwrap(); | 27 | .unwrap(); |
| 28 | for packed_ref in buffer.iter().unwrap().map(Result::unwrap) { | 28 | for packed_ref in buffer.iter().unwrap().map(Result::unwrap) { |
| 29 | let found_ref = buffer | 29 | let found_ref = buffer |
| 30 | .find_existing(packed_ref.name) | 30 | .find(packed_ref.name) |
| 31 | .expect("ref can be found as buffer is sorted"); | 31 | .expect("ref can be found as buffer is sorted"); |
| 32 | assert_eq!( | 32 | assert_eq!( |
| 33 | found_ref, packed_ref, | 33 | found_ref, packed_ref, |
| @@ -3,9 +3,8 @@ mod refedit_ext { · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | use bstr::{BString, ByteSlice}; | 4 | use bstr::{BString, ByteSlice}; |
| 5 | use git_ref::{ | 5 | use git_ref::{ |
| 6 | mutable::Target, | ||
| 7 | transaction::{Change, Create, RefEdit, RefEditsExt, RefLog}, | 6 | transaction::{Change, Create, RefEdit, RefEditsExt, RefLog}, |
| 8 | PartialName, | 7 | PartialNameRef, Target, |
| 9 | }; | 8 | }; |
| 10 | 9 | ||
| 11 | #[derive(Default)] | 10 | #[derive(Default)] |
| @@ -26,7 +25,7 @@ mod refedit_ext { · 14 unmodified lines | |||
| 26 | }, | 25 | }, |
| 27 | } | 26 | } |
| 28 | } | 27 | } |
| 29 | fn find_existing(&self, name: PartialName<'_>) -> Option<Target> { | 28 | fn find_existing(&self, name: PartialNameRef<'_>) -> Option<Target> { |
| 30 | self.targets.borrow_mut().remove(name.as_bstr()) | 29 | self.targets.borrow_mut().remove(name.as_bstr()) |
| 31 | } | 30 | } |
| 32 | } | 31 | } |
| @@ -149,16 +148,15 @@ mod refedit_ext { · 116 unmodified lines | |||
| 149 | 148 | ||
| 150 | use git_hash::ObjectId; | 149 | use git_hash::ObjectId; |
| 151 | use git_ref::{ | 150 | use git_ref::{ |
| 152 | mutable::Target, | ||
| 153 | transaction::{Change, Create, LogChange, RefEdit, RefEditsExt, RefLog}, | 151 | transaction::{Change, Create, LogChange, RefEdit, RefEditsExt, RefLog}, |
| 154 | FullName, PartialName, | 152 | FullNameRef, PartialNameRef, Target, |
| 155 | }; | 153 | }; |
| 156 | use git_testtools::hex_to_id; | 154 | use git_testtools::hex_to_id; |
| 157 | 155 | ||
| 158 | use crate::transaction::refedit_ext::MockStore; | 156 | use crate::transaction::refedit_ext::MockStore; |
| 159 | 157 | ||
| 160 | fn find<'a>(edits: &'a [RefEdit], name: &str) -> &'a RefEdit { | 158 | fn find<'a>(edits: &'a [RefEdit], name: &str) -> &'a RefEdit { |
| 161 | let name: FullName = name.try_into().unwrap(); | 159 | let name: FullNameRef = name.try_into().unwrap(); |
| 162 | edits | 160 | edits |
| 163 | .iter() | 161 | .iter() |
| 164 | .find(|e| e.name.as_bstr() == name.as_bstr()) | 162 | .find(|e| e.name.as_bstr() == name.as_bstr()) |
| @@ -229,7 +227,7 @@ mod refedit_ext { · 64 unmodified lines | |||
| 229 | next_item: Cell<bool>, | 227 | next_item: Cell<bool>, |
| 230 | } | 228 | } |
| 231 | impl Cycler { | 229 | impl Cycler { |
| 232 | fn find_existing(&self, _name: PartialName<'_>) -> Option<Target> { | 230 | fn find_existing(&self, _name: PartialNameRef<'_>) -> Option<Target> { |
| 233 | let item: bool = self.next_item.get(); | 231 | let item: bool = self.next_item.get(); |
| 234 | self.next_item.set(!item); | 232 | self.next_item.set(!item); |
| 235 | Some(Target::Symbolic( | 233 | Some(Target::Symbolic( |
| @@ -42,7 +42,7 @@ git-validate = { version = "^0.5.0", path = "../git-validate" } · 41 unmodified lines | |||
| 42 | git-odb = { version ="0.20.0", path = "../git-odb" } | 42 | git-odb = { version ="0.20.0", path = "../git-odb" } |
| 43 | git-hash = { version = "^0.5.0", path = "../git-hash" } | 43 | git-hash = { version = "^0.5.0", path = "../git-hash" } |
| 44 | git-object = { version ="0.12.0", path = "../git-object" } | 44 | git-object = { version ="0.12.0", path = "../git-object" } |
| 45 | git-actor = { version ="^0.4.0", path = "../git-actor" } | 45 | git-actor = { version ="^0.5.0", path = "../git-actor" } |
| 46 | git-pack = { version ="^0.9.0", path = "../git-pack" } | 46 | git-pack = { version ="^0.9.0", path = "../git-pack" } |
| 47 | 47 | ||
| 48 | git-url = { version = "0.3.0", path = "../git-url", optional = true } | 48 | git-url = { version = "0.3.0", path = "../git-url", optional = true } |
| @@ -10,9 +10,8 @@ use git_actor as actor; · 9 unmodified lines | |||
| 10 | use git_lock as lock; | 10 | use git_lock as lock; |
| 11 | use git_ref::{ | 11 | use git_ref::{ |
| 12 | file::find::Error, | 12 | file::find::Error, |
| 13 | mutable::Target, | ||
| 14 | transaction::{Change, Create, RefEdit}, | 13 | transaction::{Change, Create, RefEdit}, |
| 15 | PartialName, | 14 | PartialNameRef, Target, |
| 16 | }; | 15 | }; |
| 17 | 16 | ||
| 18 | /// Obtain and alter references comfortably | 17 | /// Obtain and alter references comfortably |
| @@ -77,7 +76,7 @@ pub trait ReferenceAccessExt: easy::Access + Sized { · 58 unmodified lines | |||
| 77 | 76 | ||
| 78 | fn find_reference<'a, Name, E>(&self, name: Name) -> Result<Reference<'_, Self>, reference::find::existing::Error> | 77 | fn find_reference<'a, Name, E>(&self, name: Name) -> Result<Reference<'_, Self>, reference::find::existing::Error> |
| 79 | where | 78 | where |
| 80 | Name: TryInto<PartialName<'a>, Error = E>, | 79 | Name: TryInto<PartialNameRef<'a>, Error = E>, |
| 81 | Error: From<E>, | 80 | Error: From<E>, |
| 82 | { | 81 | { |
| 83 | self.try_find_reference(name)? | 82 | self.try_find_reference(name)? |
| @@ -86,14 +85,14 @@ pub trait ReferenceAccessExt: easy::Access + Sized { · 2 unmodified lines | |||
| 86 | 85 | ||
| 87 | fn try_find_reference<'a, Name, E>(&self, name: Name) -> Result<Option<Reference<'_, Self>>, reference::find::Error> | 86 | fn try_find_reference<'a, Name, E>(&self, name: Name) -> Result<Option<Reference<'_, Self>>, reference::find::Error> |
| 88 | where | 87 | where |
| 89 | Name: TryInto<PartialName<'a>, Error = E>, | 88 | Name: TryInto<PartialNameRef<'a>, Error = E>, |
| 90 | Error: From<E>, | 89 | Error: From<E>, |
| 91 | { | 90 | { |
| 92 | let state = self.state(); | 91 | let state = self.state(); |
| 93 | let repo = self.repo()?; | 92 | let repo = self.repo()?; |
| 94 | match repo | 93 | match repo |
| 95 | .refs | 94 | .refs |
| 96 | .find(name, state.assure_packed_refs_uptodate(&repo.refs)?.as_ref()) | 95 | .try_find(name, state.assure_packed_refs_uptodate(&repo.refs)?.as_ref()) |
| 97 | { | 96 | { |
| 98 | Ok(r) => match r { | 97 | Ok(r) => match r { |
| 99 | Some(r) => Ok(Some(Reference::from_file_ref(r, self))), | 98 | Some(r) => Ok(Some(Reference::from_file_ref(r, self))), |
| @@ -12,7 +12,7 @@ use git_ref as refs; · 11 unmodified lines | |||
| 12 | pub(crate) enum Backing { | 12 | pub(crate) enum Backing { |
| 13 | OwnedPacked { | 13 | OwnedPacked { |
| 14 | /// The validated full name of the reference. | 14 | /// The validated full name of the reference. |
| 15 | name: refs::mutable::FullName, | 15 | name: refs::FullName, |
| 16 | /// The target object id of the reference, hex encoded. | 16 | /// The target object id of the reference, hex encoded. |
| 17 | target: ObjectId, | 17 | target: ObjectId, |
| 18 | /// The fully peeled object id, hex encoded, that the ref is ultimately pointing to | 18 | /// The fully peeled object id, hex encoded, that the ref is ultimately pointing to |
| @@ -107,19 +107,19 @@ where · 88 unmodified lines | |||
| 107 | access, | 107 | access, |
| 108 | } | 108 | } |
| 109 | } | 109 | } |
| 110 | pub fn target(&self) -> refs::mutable::Target { | 110 | pub fn target(&self) -> refs::Target { |
| 111 | match self.backing.as_ref().expect("always set") { | 111 | match self.backing.as_ref().expect("always set") { |
| 112 | Backing::OwnedPacked { target, .. } => refs::mutable::Target::Peeled(target.to_owned()), | 112 | Backing::OwnedPacked { target, .. } => refs::Target::Peeled(target.to_owned()), |
| 113 | Backing::LooseFile(r) => r.target.clone(), | 113 | Backing::LooseFile(r) => r.target.clone(), |
| 114 | } | 114 | } |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | pub fn name(&self) -> refs::FullName<'_> { | 117 | pub fn name(&self) -> refs::FullNameRef<'_> { |
| 118 | match self.backing.as_ref().expect("always set") { | 118 | match self.backing.as_ref().expect("always set") { |
| 119 | Backing::OwnedPacked { name, .. } => name, | 119 | Backing::OwnedPacked { name, .. } => name, |
| 120 | Backing::LooseFile(r) => &r.name, | 120 | Backing::LooseFile(r) => &r.name, |
| 121 | } | 121 | } |
| 122 | .borrow() | 122 | .to_ref() |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | pub fn peel_to_oid_in_place(&mut self) -> Result<Oid<'repo, A>, peel_to_oid_in_place::Error> { | 125 | pub fn peel_to_oid_in_place(&mut self) -> Result<Oid<'repo, A>, peel_to_oid_in_place::Error> { |
| @@ -42,7 +42,7 @@ pub fn is_git(git_dir: impl AsRef<Path>) -> Result<crate::Kind, Error> { · 41 unmodified lines | |||
| 42 | 42 | ||
| 43 | { | 43 | { |
| 44 | let refs = git_ref::file::Store::at(&dot_git, Default::default()); | 44 | let refs = git_ref::file::Store::at(&dot_git, Default::default()); |
| 45 | let head = refs.loose_find_existing("HEAD")?; | 45 | let head = refs.find_loose("HEAD")?; |
| 46 | if head.name.as_bstr() != "HEAD" { | 46 | if head.name.as_bstr() != "HEAD" { |
| 47 | return Err(Error::MisplacedHead(head.name.into_inner())); | 47 | return Err(Error::MisplacedHead(head.name.into_inner())); |
| 48 | } | 48 | } |
| @@ -19,7 +19,7 @@ mod find { · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | assert_eq!( | 20 | assert_eq!( |
| 21 | packed_tag_ref.target(), | 21 | packed_tag_ref.target(), |
| 22 | refs::mutable::Target::Peeled(hex_to_id("4c3f4cce493d7beb45012e478021b5f65295e5a3")), | 22 | refs::Target::Peeled(hex_to_id("4c3f4cce493d7beb45012e478021b5f65295e5a3")), |
| 23 | "it points to a tag object" | 23 | "it points to a tag object" |
| 24 | ); | 24 | ); |
| 25 | 25 | ||
| @@ -49,7 +49,7 @@ where · 48 unmodified lines | |||
| 49 | let packed = repo.refs.packed_buffer()?; | 49 | let packed = repo.refs.packed_buffer()?; |
| 50 | let commit_id = repo | 50 | let commit_id = repo |
| 51 | .refs | 51 | .refs |
| 52 | .find_existing(refname.to_string_lossy().as_ref(), packed.as_ref())? | 52 | .find(refname.to_string_lossy().as_ref(), packed.as_ref())? |
| 53 | .peel_to_id_in_place(&repo.refs, packed.as_ref(), |oid, buf| { | 53 | .peel_to_id_in_place(&repo.refs, packed.as_ref(), |oid, buf| { |
| 54 | repo.odb | 54 | repo.odb |
| 55 | .find(oid, buf, &mut pack::cache::Never) | 55 | .find(oid, buf, &mut pack::cache::Never) |
| @@ -117,7 +117,7 @@ where · 116 unmodified lines | |||
| 117 | let refs = &repo.refs; | 117 | let refs = &repo.refs; |
| 118 | let repo = Arc::clone(&repo); | 118 | let repo = Arc::clone(&repo); |
| 119 | move |_| { | 119 | move |_| { |
| 120 | refs.find_existing(tip.as_ref().to_string_lossy().as_ref(), packed.as_ref()) | 120 | refs.find(tip.as_ref().to_string_lossy().as_ref(), packed.as_ref()) |
| 121 | .map_err(anyhow::Error::from) | 121 | .map_err(anyhow::Error::from) |
| 122 | .and_then(|mut r| { | 122 | .and_then(|mut r| { |
| 123 | r.peel_to_id_in_place(refs, packed.as_ref(), |oid, buf| { | 123 | r.peel_to_id_in_place(refs, packed.as_ref(), |oid, buf| { |