diff --git a/Cargo.lock b/Cargo.lock index fb01bc2aa95..06af5eee446 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -985,7 +985,7 @@ dependencies = [ [[package]] name = "git-actor" -version = "0.4.0" +version = "0.5.0" dependencies = [ "bstr", "btoi", diff --git a/cargo-smart-release/src/command/release/git.rs b/cargo-smart-release/src/command/release/git.rs index 0e8407a3625..0048edd93a4 100644 --- a/cargo-smart-release/src/command/release/git.rs +++ b/cargo-smart-release/src/command/release/git.rs @@ -141,7 +141,7 @@ pub(in crate::command::release_impl) fn create_version_tag<'repo>( skip_tag, .. }: Options, -) -> anyhow::Result> { +) -> anyhow::Result> { if skip_tag { return Ok(None); } @@ -170,10 +170,7 @@ pub(in crate::command::release_impl) fn create_version_tag<'repo>( } // TODO: Make this gitoxide -pub fn push_tags_and_head( - tag_names: impl IntoIterator, - options: Options, -) -> anyhow::Result<()> { +pub fn push_tags_and_head(tag_names: impl IntoIterator, options: Options) -> anyhow::Result<()> { if options.skip_push { return Ok(()); } diff --git a/git-actor/Cargo.toml b/git-actor/Cargo.toml index 39df7fb177c..87adb2415d4 100644 --- a/git-actor/Cargo.toml +++ b/git-actor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "git-actor" -version = "0.4.0" +version = "0.5.0" description = "A way to identify git actors" authors = ["Sebastian Thiel "] repository = "https://github.com/Byron/gitoxide" diff --git a/git-actor/src/lib.rs b/git-actor/src/lib.rs index ceeb42bb635..d0a5eed386c 100644 --- a/git-actor/src/lib.rs +++ b/git-actor/src/lib.rs @@ -5,8 +5,6 @@ use bstr::{BStr, BString}; /// pub mod signature; -/// -pub mod signature_ref; const SPACE: &[u8; 1] = b" "; diff --git a/git-actor/src/signature_ref/decode.rs b/git-actor/src/signature/decode.rs similarity index 97% rename from git-actor/src/signature_ref/decode.rs rename to git-actor/src/signature/decode.rs index 0b03876565e..75c60beccc4 100644 --- a/git-actor/src/signature_ref/decode.rs +++ b/git-actor/src/signature/decode.rs @@ -68,13 +68,10 @@ mod tests { use git_testtools::to_bstr_err; use nom::IResult; - use crate::{ - signature_ref::{self, SignatureRef}, - Sign, Time, - }; + use crate::{signature, Sign, SignatureRef, Time}; fn decode(i: &[u8]) -> IResult<&[u8], SignatureRef<'_>, nom::error::VerboseError<&[u8]>> { - signature_ref::decode(i) + signature::decode(i) } fn signature( diff --git a/git-actor/src/signature.rs b/git-actor/src/signature/mod.rs similarity index 84% rename from git-actor/src/signature.rs rename to git-actor/src/signature/mod.rs index 16cdebdef30..283069b1154 100644 --- a/git-actor/src/signature.rs +++ b/git-actor/src/signature/mod.rs @@ -1,3 +1,16 @@ +mod _ref { + use crate::{signature::decode, SignatureRef}; + + impl<'a> SignatureRef<'a> { + /// Deserialize a signature from the given `data`. + pub fn from_bytes + nom::error::ContextError<&'a [u8]>>( + data: &'a [u8], + ) -> Result, nom::Err> { + decode(data).map(|(_, t)| t) + } + } +} + mod convert { use crate::{Sign, Signature, SignatureRef, Time}; @@ -85,3 +98,7 @@ mod write { Ok(name) } } + +/// +mod decode; +pub use decode::decode; diff --git a/git-actor/src/signature_ref/mod.rs b/git-actor/src/signature_ref/mod.rs deleted file mode 100644 index 0d0a3e4c239..00000000000 --- a/git-actor/src/signature_ref/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -use crate::SignatureRef; - -impl<'a> SignatureRef<'a> { - /// Deserialize a signature from the given `data`. - pub fn from_bytes + nom::error::ContextError<&'a [u8]>>( - data: &'a [u8], - ) -> Result, nom::Err> { - decode(data).map(|(_, t)| t) - } -} - -/// -mod decode; -pub use decode::decode; diff --git a/git-object/Cargo.toml b/git-object/Cargo.toml index 7b62cad211f..11fb434e006 100644 --- a/git-object/Cargo.toml +++ b/git-object/Cargo.toml @@ -21,7 +21,7 @@ all-features = true [dependencies] git-hash = { version = "^0.5.0", path = "../git-hash" } git-validate = { version = "^0.5.0", path = "../git-validate" } -git-actor = { version ="^0.4.0", path = "../git-actor" } +git-actor = { version ="^0.5.0", path = "../git-actor" } quick-error = "2.0.0" hex = "0.4.2" diff --git a/git-object/src/immutable/parse.rs b/git-object/src/immutable/parse.rs index a73147d494c..52f43216a0e 100644 --- a/git-object/src/immutable/parse.rs +++ b/git-object/src/immutable/parse.rs @@ -77,5 +77,5 @@ pub fn hex_hash<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], & pub(crate) fn signature<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>( i: &'a [u8], ) -> IResult<&'a [u8], git_actor::SignatureRef<'a>, E> { - git_actor::signature_ref::decode(i) + git_actor::signature::decode(i) } diff --git a/git-object/src/types.rs b/git-object/src/types.rs index af87e3da92a..73212d7d27d 100644 --- a/git-object/src/types.rs +++ b/git-object/src/types.rs @@ -56,7 +56,7 @@ impl fmt::Display for Kind { pub mod tree { /// The mode of items storable in a tree, similar to the file mode on a unix file system. /// - /// Used in [mutable::Entry][crate::mutable::tree::Entry] and [signature_ref::Entry][crate::immutable::tree::Entry]. + /// Used in [mutable::Entry][crate::mutable::tree::Entry] and [tree::Entry][crate::immutable::tree::Entry]. #[derive(Clone, Copy, PartialEq, Eq, Debug, Ord, PartialOrd, Hash)] #[repr(u16)] #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] diff --git a/git-ref/Cargo.toml b/git-ref/Cargo.toml index b5c8188a6a0..0f1f7e081c3 100644 --- a/git-ref/Cargo.toml +++ b/git-ref/Cargo.toml @@ -28,7 +28,7 @@ git-features = { version = "^0.16.0", path = "../git-features", features = ["wal git-hash = { version = "^0.5.0", path = "../git-hash" } git-object = { version ="0.12.0", path = "../git-object" } git-validate = { version = "^0.5.0", path = "../git-validate" } -git-actor = { version ="^0.4.0", path = "../git-actor" } +git-actor = { version ="^0.5.0", path = "../git-actor" } git-lock = { version ="^1.0.0", path = "../git-lock" } git-tempfile = { version ="^1.0.0", path = "../git-tempfile" } diff --git a/git-ref/src/fullname.rs b/git-ref/src/fullname.rs new file mode 100644 index 00000000000..df8eaf7a43c --- /dev/null +++ b/git-ref/src/fullname.rs @@ -0,0 +1,71 @@ +use std::{borrow::Cow, convert::TryFrom, path::Path}; + +use bstr::{BStr, BString, ByteSlice}; + +use crate::FullName; + +impl TryFrom<&str> for FullName { + type Error = git_validate::refname::Error; + + fn try_from(value: &str) -> Result { + Ok(FullName(git_validate::refname(value.as_bytes().as_bstr())?.into())) + } +} + +impl TryFrom for FullName { + type Error = git_validate::refname::Error; + + fn try_from(value: String) -> Result { + git_validate::refname(value.as_bytes().as_bstr())?; + Ok(FullName(value.into())) + } +} + +impl TryFrom<&BStr> for FullName { + type Error = git_validate::refname::Error; + + fn try_from(value: &BStr) -> Result { + Ok(FullName(git_validate::refname(value)?.into())) + } +} + +impl TryFrom for FullName { + type Error = git_validate::refname::Error; + + fn try_from(value: BString) -> Result { + git_validate::refname(value.as_ref())?; + Ok(FullName(value)) + } +} + +impl<'a> From> for FullName { + fn from(value: crate::FullNameRef<'a>) -> Self { + FullName(value.as_bstr().into()) + } +} + +impl FullName { + /// Interpret this fully qualified reference name as partial name. + pub fn to_partial(&self) -> crate::PartialNameRef<'_> { + crate::PartialNameRef(self.0.as_bstr()) + } + + /// Interpret this fully qualified reference as shared full name + pub fn to_ref(&self) -> crate::FullNameRef<'_> { + crate::FullNameRef(self.0.as_bstr()) + } + + /// Convert this name into the relative path, lossily, identifying the reference location relative to a repository + pub fn to_path(&self) -> Cow<'_, Path> { + self.0.to_path().expect("UTF-8 conversion always succeeds").into() + } + + /// Dissolve this instance and return the buffer. + pub fn into_inner(self) -> BString { + self.0 + } + /// Return ourselves as byte string which is a valid refname + pub fn as_bstr(&self) -> &BStr { + self.0.as_bstr() + } +} diff --git a/git-ref/src/lib.rs b/git-ref/src/lib.rs index 90ddbaba0a0..63b4288f593 100644 --- a/git-ref/src/lib.rs +++ b/git-ref/src/lib.rs @@ -19,12 +19,12 @@ #![forbid(unsafe_code)] #![deny(missing_docs, rust_2018_idioms)] use bstr::{BStr, BString}; -use git_hash::oid; +use git_hash::{oid, ObjectId}; mod store; pub use store::{file, packed}; -/// -pub mod mutable; + +mod fullname; /// pub mod name; /// @@ -32,12 +32,17 @@ pub mod namespace; /// pub mod transaction; +/// Indicate that the given BString is a validate reference name or path that can be used as path on disk or written as target +/// of a symbolic reference +#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] +pub struct FullName(pub(crate) BString); + /// A validated and potentially partial reference name - it can safely be used for common operations. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] -pub struct FullName<'a>(&'a BStr); +pub struct FullNameRef<'a>(&'a BStr); /// A validated complete and fully qualified reference name, safe to use for all operations. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] -pub struct PartialName<'a>(&'a BStr); +pub struct PartialNameRef<'a>(&'a BStr); /// A validated prefix for references to act as a namespace. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] @@ -55,9 +60,20 @@ pub enum Kind { Symbolic, } +/// Denotes a ref target, equivalent to [`Kind`], but with mutable data. +#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] +pub enum Target { + /// A ref that points to an object id + Peeled(ObjectId), + /// A ref that points to another reference by its validated name, adding a level of indirection. + /// + /// Note that this is an extension of gitoxide which will be helpful in logging all reference changes. + Symbolic(FullName), +} + /// Denotes a ref target, equivalent to [`Kind`], but with signature_ref data. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] -pub enum Target<'a> { +pub enum TargetRef<'a> { /// A ref that points to an object id Peeled(&'a oid), /// A ref that points to another reference by its validated name, adding a level of indirection. diff --git a/git-ref/src/mutable.rs b/git-ref/src/mutable.rs deleted file mode 100644 index 41dfda34410..00000000000 --- a/git-ref/src/mutable.rs +++ /dev/null @@ -1,162 +0,0 @@ -use std::{borrow::Cow, convert::TryFrom, fmt, path::Path}; - -use bstr::{BStr, BString, ByteSlice}; -use git_hash::{oid, ObjectId}; - -use crate::Kind; - -/// Indicate that the given BString is a validate reference name or path that can be used as path on disk or written as target -/// of a symbolic reference -#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] -pub struct FullName(pub(crate) BString); - -impl TryFrom<&str> for FullName { - type Error = git_validate::refname::Error; - - fn try_from(value: &str) -> Result { - Ok(FullName(git_validate::refname(value.as_bytes().as_bstr())?.into())) - } -} - -impl TryFrom for FullName { - type Error = git_validate::refname::Error; - - fn try_from(value: String) -> Result { - git_validate::refname(value.as_bytes().as_bstr())?; - Ok(FullName(value.into())) - } -} - -impl TryFrom<&BStr> for FullName { - type Error = git_validate::refname::Error; - - fn try_from(value: &BStr) -> Result { - Ok(FullName(git_validate::refname(value)?.into())) - } -} - -impl TryFrom for FullName { - type Error = git_validate::refname::Error; - - fn try_from(value: BString) -> Result { - git_validate::refname(value.as_ref())?; - Ok(FullName(value)) - } -} - -impl<'a> From> for FullName { - fn from(value: crate::FullName<'a>) -> Self { - FullName(value.as_bstr().into()) - } -} - -impl FullName { - /// Interpret this fully qualified reference name as partial name. - pub fn to_partial(&self) -> crate::PartialName<'_> { - crate::PartialName(self.0.as_bstr()) - } - - /// Interpret this fully qualified reference as shared full name - pub fn borrow(&self) -> crate::FullName<'_> { - crate::FullName(self.0.as_bstr()) - } - - /// Convert this name into the relative path, lossily, identifying the reference location relative to a repository - pub fn to_path(&self) -> Cow<'_, Path> { - self.0.to_path().expect("UTF-8 conversion always succeeds").into() - } - - /// Dissolve this instance and return the buffer. - pub fn into_inner(self) -> BString { - self.0 - } - /// Return ourselves as byte string which is a valid refname - pub fn as_bstr(&self) -> &BStr { - self.0.as_bstr() - } -} - -/// Denotes a ref target, equivalent to [`Kind`][super::Kind], but with mutable data. -#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] -pub enum Target { - /// A ref that points to an object id - Peeled(ObjectId), - /// A ref that points to another reference by its validated name, adding a level of indirection. - /// - /// Note that this is an extension of gitoxide which will be helpful in logging all reference changes. - Symbolic(FullName), -} - -impl Target { - /// Returns the kind of the target the ref is pointing to. - pub fn kind(&self) -> Kind { - match self { - Target::Symbolic(_) => Kind::Symbolic, - Target::Peeled(_) => Kind::Peeled, - } - } - - /// Return true if this is a peeled target with a null hash - pub fn is_null(&self) -> bool { - match self { - Target::Peeled(oid) => oid.is_null(), - Target::Symbolic(_) => false, - } - } - - /// Interpret this owned Target as shared Target - pub fn borrow(&self) -> crate::Target<'_> { - match self { - Target::Peeled(oid) => crate::Target::Peeled(oid), - Target::Symbolic(name) => crate::Target::Symbolic(name.0.as_bstr()), - } - } - - /// Interpret this target as object id which maybe `None` if it is symbolic. - pub fn as_id(&self) -> Option<&oid> { - match self { - Target::Symbolic(_) => None, - Target::Peeled(oid) => Some(oid), - } - } - /// Interpret this target as name of the reference it points to which maybe `None` if it an object id. - pub fn as_name(&self) -> Option<&BStr> { - match self { - Target::Symbolic(name) => Some(name.as_bstr()), - Target::Peeled(_) => None, - } - } - - /// Create an instance that signals that a reference should exist if this value is used in a [`Change`][crate::transaction::Change]. - pub fn must_exist() -> Self { - Target::Peeled(ObjectId::null_sha1()) - } -} - -impl<'a> From> for Target { - fn from(src: crate::Target<'a>) -> Self { - match src { - crate::Target::Peeled(oid) => Target::Peeled(oid.to_owned()), - crate::Target::Symbolic(name) => Target::Symbolic(FullName(name.to_owned())), - } - } -} - -impl<'a> PartialEq> for Target { - fn eq(&self, other: &crate::Target<'a>) -> bool { - match (self, other) { - (Target::Peeled(lhs), crate::Target::Peeled(rhs)) => lhs == rhs, - (Target::Symbolic(lhs), crate::Target::Symbolic(rhs)) => lhs.as_bstr() == *rhs, - _ => false, - } - } -} - -impl fmt::Display for Target { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Target::Peeled(oid) => oid.fmt(f), - Target::Symbolic(name) => write!(f, "ref: {}", name.as_bstr()), - } - } -} diff --git a/git-ref/src/name.rs b/git-ref/src/name.rs index c08fa899170..4613335f8fe 100644 --- a/git-ref/src/name.rs +++ b/git-ref/src/name.rs @@ -6,12 +6,12 @@ use std::{ use bstr::{BStr, ByteSlice}; -use crate::{FullName, PartialName}; +use crate::{FullNameRef, PartialNameRef}; -/// The error used in the [`PartialName`][super::PartialName]::try_from(…) implementations. +/// The error used in the [`PartialNameRef`][super::PartialNameRef]::try_from(…) implementations. pub type Error = git_validate::reference::name::Error; -impl<'a> FullName<'a> { +impl<'a> FullNameRef<'a> { /// Convert this name into the relative path identifying the reference location. pub fn to_path(self) -> Cow<'a, Path> { self.0.to_path().expect("UTF-8 conversion always succeeds").into() @@ -23,7 +23,7 @@ impl<'a> FullName<'a> { } } -impl<'a> PartialName<'a> { +impl<'a> PartialNameRef<'a> { /// Convert this name into the relative path possibly identifying the reference location. /// Note that it may be only a partial path though. pub fn to_partial_path(self) -> Cow<'a, Path> { @@ -36,62 +36,62 @@ impl<'a> PartialName<'a> { } } -impl<'a> TryFrom<&'a BStr> for FullName<'a> { +impl<'a> TryFrom<&'a BStr> for FullNameRef<'a> { type Error = Error; fn try_from(v: &'a BStr) -> Result { - Ok(FullName(git_validate::reference::name(v)?)) + Ok(FullNameRef(git_validate::reference::name(v)?)) } } -impl<'a> TryFrom> for PartialName<'a> { +impl<'a> TryFrom> for PartialNameRef<'a> { type Error = Infallible; - fn try_from(v: FullName<'a>) -> Result { - Ok(PartialName(v.0)) + fn try_from(v: FullNameRef<'a>) -> Result { + Ok(PartialNameRef(v.0)) } } -impl<'a> TryFrom<&'a BStr> for PartialName<'a> { +impl<'a> TryFrom<&'a BStr> for PartialNameRef<'a> { type Error = Error; fn try_from(v: &'a BStr) -> Result { - Ok(PartialName(git_validate::reference::name_partial(v)?)) + Ok(PartialNameRef(git_validate::reference::name_partial(v)?)) } } -impl<'a> TryFrom<&'a str> for FullName<'a> { +impl<'a> TryFrom<&'a str> for FullNameRef<'a> { type Error = Error; fn try_from(v: &'a str) -> Result { let v = v.as_bytes().as_bstr(); - Ok(FullName(git_validate::reference::name(v)?)) + Ok(FullNameRef(git_validate::reference::name(v)?)) } } -impl<'a> TryFrom<&'a str> for PartialName<'a> { +impl<'a> TryFrom<&'a str> for PartialNameRef<'a> { type Error = Error; fn try_from(v: &'a str) -> Result { let v = v.as_bytes().as_bstr(); - Ok(PartialName(git_validate::reference::name_partial(v)?)) + Ok(PartialNameRef(git_validate::reference::name_partial(v)?)) } } -impl<'a> TryFrom<&'a String> for FullName<'a> { +impl<'a> TryFrom<&'a String> for FullNameRef<'a> { type Error = Error; fn try_from(v: &'a String) -> Result { let v = v.as_bytes().as_bstr(); - Ok(FullName(git_validate::reference::name(v)?)) + Ok(FullNameRef(git_validate::reference::name(v)?)) } } -impl<'a> TryFrom<&'a String> for PartialName<'a> { +impl<'a> TryFrom<&'a String> for PartialNameRef<'a> { type Error = Error; fn try_from(v: &'a String) -> Result { let v = v.as_bytes().as_bstr(); - Ok(PartialName(git_validate::reference::name_partial(v)?)) + Ok(PartialNameRef(git_validate::reference::name_partial(v)?)) } } diff --git a/git-ref/src/namespace.rs b/git-ref/src/namespace.rs index ae8d4b68601..9cc9ec3d435 100644 --- a/git-ref/src/namespace.rs +++ b/git-ref/src/namespace.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, convert::TryInto, path::Path}; use bstr::{BStr, BString, ByteSlice, ByteVec}; -use crate::{Namespace, PartialName}; +use crate::{Namespace, PartialNameRef}; impl Namespace { /// Dissolve ourselves into the interior representation @@ -24,7 +24,7 @@ impl Namespace { /// For more information, consult the [git namespace documentation](https://git-scm.com/docs/gitnamespaces). pub fn expand<'a, Name, E>(namespace: Name) -> Result where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, git_validate::refname::Error: From, { let namespace = namespace.try_into()?.0; diff --git a/git-ref/src/store/file/find.rs b/git-ref/src/store/file/find.rs index b970be72a71..4ea8bac708d 100644 --- a/git-ref/src/store/file/find.rs +++ b/git-ref/src/store/file/find.rs @@ -9,12 +9,11 @@ pub use error::Error; use crate::{ file, - mutable::FullName, store::{ file::{loose, path_to_name}, packed, }, - PartialName, + FullName, PartialNameRef, }; enum Transform { @@ -41,7 +40,7 @@ impl file::Store { packed: Option<&'p packed::Buffer>, ) -> Result>, Error> where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, Error: From, { let path = partial.try_into()?; @@ -51,7 +50,7 @@ impl file::Store { /// Similar to [`file::Store::find()`] but a non-existing ref is treated as error. pub fn loose_find<'a, Name, E>(&self, partial: Name) -> Result, Error> where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, Error: From, { self.find(partial, None) @@ -116,7 +115,7 @@ impl file::Store { if is_definitely_absolute { if let Some(packed) = packed { let full_name = path_to_name(relative_path); - let full_name = PartialName((*full_name).as_bstr()); + let full_name = PartialNameRef((*full_name).as_bstr()); if let Some(packed_ref) = packed.find(full_name)? { return Ok(Some(file::Reference::Packed(packed_ref))); }; @@ -173,7 +172,7 @@ pub mod existing { file::{find, loose}, packed, }, - PartialName, + PartialNameRef, }; impl file::Store { @@ -184,7 +183,7 @@ pub mod existing { packed: Option<&'p packed::Buffer>, ) -> Result, Error> where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, crate::name::Error: From, { let path = partial @@ -200,7 +199,7 @@ pub mod existing { /// Similar to [`file::Store::find()`] won't handle packed-refs. pub fn loose_find_existing<'a, Name, E>(&self, partial: Name) -> Result where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, crate::name::Error: From, { self.find_existing(partial, None) diff --git a/git-ref/src/store/file/log/iter.rs b/git-ref/src/store/file/log/iter.rs index fa8d05537d5..9b40387a949 100644 --- a/git-ref/src/store/file/log/iter.rs +++ b/git-ref/src/store/file/log/iter.rs @@ -1,5 +1,6 @@ use bstr::ByteSlice; +use crate::store::file; use crate::store::file::{log, log::iter::decode::LineNumber}; /// @@ -51,9 +52,9 @@ pub mod decode { /// This iterator is useful when the ref log file is going to be rewritten which forces processing of the entire file. /// It will continue parsing even if individual log entries failed to parse, leaving it to the driver to decide whether to /// abort or continue. -pub fn forward(lines: &[u8]) -> impl Iterator, decode::Error>> { +pub fn forward(lines: &[u8]) -> impl Iterator, decode::Error>> { lines.as_bstr().lines().enumerate().map(|(ln, line)| { - log::Line::from_bytes(line).map_err(|err| decode::Error::new(err, decode::LineNumber::FromStart(ln))) + log::LineRef::from_bytes(line).map_err(|err| decode::Error::new(err, decode::LineNumber::FromStart(ln))) }) } @@ -93,7 +94,7 @@ impl<'a, F> Iterator for Reverse<'a, F> where F: std::io::Read + std::io::Seek, { - type Item = std::io::Result>; + type Item = std::io::Result>; fn next(&mut self) -> Option { match (self.last_nl_pos.take(), self.read_and_pos.take()) { @@ -124,7 +125,7 @@ where self.read_and_pos = Some(read_and_pos); self.last_nl_pos = Some(start); let buf = &self.buf[start + 1..end]; - let res = Some(Ok(log::Line::from_bytes(buf) + let res = Some(Ok(log::LineRef::from_bytes(buf) .map_err(|err| decode::Error::new(err, LineNumber::FromEnd(self.count))) .map(Into::into))); self.count += 1; @@ -134,7 +135,7 @@ where let (mut read, last_read_pos) = read_and_pos; if last_read_pos == 0 { let buf = &self.buf[..end]; - Some(Ok(log::Line::from_bytes(buf) + Some(Ok(log::LineRef::from_bytes(buf) .map_err(|err| decode::Error::new(err, LineNumber::FromEnd(self.count))) .map(Into::into))) } else { diff --git a/git-ref/src/store/file/log/line.rs b/git-ref/src/store/file/log/line.rs index 13864919d33..4b693b6d968 100644 --- a/git-ref/src/store/file/log/line.rs +++ b/git-ref/src/store/file/log/line.rs @@ -1,8 +1,59 @@ use git_hash::ObjectId; use crate::store::file::log::Line; +use crate::store::file::log::LineRef; -impl<'a> Line<'a> { +impl<'a> LineRef<'a> { + /// Convert this instance into its mutable counterpart + pub fn to_owned(&self) -> Line { + self.clone().into() + } +} + +mod write { + use std::io; + + use bstr::{BStr, ByteSlice}; + use quick_error::quick_error; + + use crate::store::file::log::Line; + + quick_error! { + /// The Error produced by [`Line::write_to()`] (but wrapped in an io error). + #[derive(Debug)] + #[allow(missing_docs)] + enum Error { + IllegalCharacter { + display("Messages must not contain newlines\\n") + } + } + } + + impl From for io::Error { + fn from(err: Error) -> Self { + io::Error::new(io::ErrorKind::Other, err) + } + } + + /// Output + impl Line { + /// Serialize this instance to `out` in the git serialization format for ref log lines. + pub fn write_to(&self, mut out: impl io::Write) -> io::Result<()> { + write!(out, "{} {} ", self.previous_oid, self.new_oid)?; + self.signature.write_to(&mut out)?; + writeln!(out, "\t{}", check_newlines(self.message.as_ref())?) + } + } + + fn check_newlines(input: &BStr) -> Result<&BStr, Error> { + if input.find_byte(b'\n').is_some() { + return Err(Error::IllegalCharacter); + } + Ok(input) + } +} + +impl<'a> LineRef<'a> { /// The previous object id of the ref. It will be a null hash if there was no previous id as /// this ref is being created. pub fn previous_oid(&self) -> ObjectId { @@ -14,6 +65,17 @@ impl<'a> Line<'a> { } } +impl<'a> From> for Line { + fn from(v: LineRef<'a>) -> Self { + Line { + previous_oid: v.previous_oid(), + new_oid: v.new_oid(), + signature: v.signature.into(), + message: v.message.into(), + } + } +} + /// pub mod decode { use bstr::{BStr, ByteSlice}; @@ -25,7 +87,7 @@ pub mod decode { IResult, }; - use crate::{file::log::Line, parse::hex_hash}; + use crate::{file::log::LineRef, parse::hex_hash}; /// mod error { @@ -59,9 +121,9 @@ pub mod decode { } pub use error::Error; - impl<'a> Line<'a> { + impl<'a> LineRef<'a> { /// Decode a line from the given bytes which are expected to start at a hex sha. - pub fn from_bytes(input: &'a [u8]) -> Result, Error> { + pub fn from_bytes(input: &'a [u8]) -> Result, Error> { one::<()>(input).map(|(_, l)| l).map_err(|_| Error::new(input)) } } @@ -74,13 +136,13 @@ pub mod decode { } } - fn one<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(bytes: &'a [u8]) -> IResult<&[u8], Line<'a>, E> { + fn one<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(bytes: &'a [u8]) -> IResult<&[u8], LineRef<'a>, E> { let (i, (old, new, signature, message_sep, message)) = context( " <> \\t", tuple(( context("", terminated(hex_hash, tag(b" "))), context("", terminated(hex_hash, tag(b" "))), - context(" <> ", git_actor::signature_ref::decode), + context(" <> ", git_actor::signature::decode), opt(tag(b"\t")), context("", message), )), @@ -100,7 +162,7 @@ pub mod decode { Ok(( i, - Line { + LineRef { previous_oid: old, new_oid: new, signature, @@ -161,7 +223,7 @@ pub mod decode { for input in &[line_without_nl, line_with_nl] { assert_eq!( one::>(input).expect("successful parsing").1, - Line { + LineRef { previous_oid: NULL_SHA1.as_bstr(), new_oid: NULL_SHA1.as_bstr(), signature: git_actor::SignatureRef { @@ -187,7 +249,7 @@ pub mod decode { for input in &[line_without_nl, line_with_nl] { let (remaining, res) = one::>(input).expect("successful parsing"); assert!(remaining.is_empty(), "all consuming even without trailing newline"); - let actual = Line { + let actual = LineRef { previous_oid: b"a5828ae6b52137b913b978e16cd2334482eb4c1f".as_bstr(), new_oid: b"89b43f80a514aee58b662ad606e6352e03eaeee4".as_bstr(), signature: git_actor::SignatureRef { diff --git a/git-ref/src/store/file/log/mod.rs b/git-ref/src/store/file/log/mod.rs index 5cf4951ca5b..9d53a15fd23 100644 --- a/git-ref/src/store/file/log/mod.rs +++ b/git-ref/src/store/file/log/mod.rs @@ -1,15 +1,22 @@ use bstr::BStr; +use git_hash::ObjectId; +use git_object::bstr::BString; + pub use super::loose::reflog::{create_or_update, Error}; +/// +pub mod iter; +mod line; + /// A parsed ref log line. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] #[non_exhaustive] -pub struct Line<'a> { - /// The previous object id in hexadecimal. Use [`Line::previous_oid()`] to get a more usable form. +pub struct LineRef<'a> { + /// The previous object id in hexadecimal. Use [`LineRef::previous_oid()`] to get a more usable form. pub previous_oid: &'a BStr, - /// The new object id in hexadecimal. Use [`Line::new_oid()`] to get a more usable form. + /// The new object id in hexadecimal. Use [`LineRef::new_oid()`] to get a more usable form. pub new_oid: &'a BStr, /// The signature of the currently configured committer. #[cfg_attr(feature = "serde1", serde(borrow))] @@ -18,87 +25,16 @@ pub struct Line<'a> { pub message: &'a BStr, } -/// -pub mod mutable { - use bstr::BString; - use git_hash::ObjectId; - - /// A parsed ref log line that can be changed - #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] - #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] - pub struct Line { - /// The previous object id. Can be a null-sha to indicate this is a line for a new ref. - pub previous_oid: ObjectId, - /// The new object id. Can be a null-sha to indicate this ref is being deleted. - pub new_oid: ObjectId, - /// The signature of the currently configured committer. - pub signature: git_actor::Signature, - /// The message providing details about the operation performed in this log line. - pub message: BString, - } - - impl<'a> From> for Line { - fn from(v: super::Line<'a>) -> Self { - Line { - previous_oid: v.previous_oid(), - new_oid: v.new_oid(), - signature: v.signature.into(), - message: v.message.into(), - } - } - } - - impl<'a> super::Line<'a> { - /// Convert this instance into its mutable counterpart - pub fn to_mutable(&self) -> Line { - self.clone().into() - } - } - - mod write { - use std::io; - - use bstr::{BStr, ByteSlice}; - use quick_error::quick_error; - - use super::Line; - - quick_error! { - /// The Error produced by [`Line::write_to()`] (but wrapped in an io error). - #[derive(Debug)] - #[allow(missing_docs)] - enum Error { - IllegalCharacter { - display("Messages must not contain newlines\\n") - } - } - } - - impl From for io::Error { - fn from(err: Error) -> Self { - io::Error::new(io::ErrorKind::Other, err) - } - } - - /// Output - impl Line { - /// Serialize this instance to `out` in the git serialization format for ref log lines. - pub fn write_to(&self, mut out: impl io::Write) -> io::Result<()> { - write!(out, "{} {} ", self.previous_oid, self.new_oid)?; - self.signature.write_to(&mut out)?; - writeln!(out, "\t{}", check_newlines(self.message.as_ref())?) - } - } - - fn check_newlines(input: &BStr) -> Result<&BStr, Error> { - if input.find_byte(b'\n').is_some() { - return Err(Error::IllegalCharacter); - } - Ok(input) - } - } +/// A parsed ref log line that can be changed +#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] +#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] +pub struct Line { + /// The previous object id. Can be a null-sha to indicate this is a line for a new ref. + pub previous_oid: ObjectId, + /// The new object id. Can be a null-sha to indicate this ref is being deleted. + pub new_oid: ObjectId, + /// The signature of the currently configured committer. + pub signature: git_actor::Signature, + /// The message providing details about the operation performed in this log line. + pub message: BString, } - -/// -pub mod iter; -mod line; diff --git a/git-ref/src/store/file/loose/iter.rs b/git-ref/src/store/file/loose/iter.rs index c9607e1ddb1..2e5bd6d9c1f 100644 --- a/git-ref/src/store/file/loose/iter.rs +++ b/git-ref/src/store/file/loose/iter.rs @@ -8,8 +8,8 @@ use git_features::fs::walkdir::DirEntryIter; use os_str_bytes::OsStrBytes; use crate::{ - mutable::FullName, store::file::{self, loose::Reference}, + FullName, }; /// An iterator over all valid loose reference paths as seen from a particular base directory. diff --git a/git-ref/src/store/file/loose/mod.rs b/git-ref/src/store/file/loose/mod.rs index 2d1e63fdb34..1278830e24b 100644 --- a/git-ref/src/store/file/loose/mod.rs +++ b/git-ref/src/store/file/loose/mod.rs @@ -1,12 +1,12 @@ -use crate::{mutable, Kind}; +use crate::{FullName, Kind, Target}; /// A git _ref_ which is stored in a file. #[derive(Debug, PartialOrd, PartialEq, Ord, Eq, Hash, Clone)] pub struct Reference { /// The path to uniquely identify this ref within its store. - pub name: mutable::FullName, + pub name: FullName, /// The target of the reference, either a symbolic reference by full name or an object by its id. - pub target: mutable::Target, + pub target: Target, } impl Reference { diff --git a/git-ref/src/store/file/loose/reference/decode.rs b/git-ref/src/store/file/loose/reference/decode.rs index f756839cc40..c59c1f9802f 100644 --- a/git-ref/src/store/file/loose/reference/decode.rs +++ b/git-ref/src/store/file/loose/reference/decode.rs @@ -11,9 +11,9 @@ use nom::{ use quick_error::quick_error; use crate::{ - mutable, parse::{hex_hash, newline}, store::file::loose::Reference, + FullName, Target, }; enum MaybeUnsafeState { @@ -36,18 +36,16 @@ quick_error! { } } -impl TryFrom for mutable::Target { +impl TryFrom for Target { type Error = Error; fn try_from(v: MaybeUnsafeState) -> Result { Ok(match v { - MaybeUnsafeState::Id(id) => mutable::Target::Peeled(id), - MaybeUnsafeState::UnvalidatedPath(name) => { - mutable::Target::Symbolic(match git_validate::refname(name.as_ref()) { - Ok(_) => mutable::FullName(name), - Err(err) => return Err(Error::RefnameValidation { err, path: name }), - }) - } + MaybeUnsafeState::Id(id) => Target::Peeled(id), + MaybeUnsafeState::UnvalidatedPath(name) => Target::Symbolic(match git_validate::refname(name.as_ref()) { + Ok(_) => FullName(name), + Err(err) => return Err(Error::RefnameValidation { err, path: name }), + }), }) } } @@ -55,7 +53,7 @@ impl TryFrom for mutable::Target { impl Reference { /// Create a new reference of the given `parent` store with `relative_path` service as unique identifier /// at which the `path_contents` was read to obtain the refs value. - pub fn try_from_path(name: mutable::FullName, path_contents: &[u8]) -> Result { + pub fn try_from_path(name: FullName, path_contents: &[u8]) -> Result { Ok(Reference { name, target: parse(path_contents) diff --git a/git-ref/src/store/file/loose/reference/logiter.rs b/git-ref/src/store/file/loose/reference/logiter.rs index b6eacd8e8ec..0b6ee882105 100644 --- a/git-ref/src/store/file/loose/reference/logiter.rs +++ b/git-ref/src/store/file/loose/reference/logiter.rs @@ -18,7 +18,7 @@ impl Reference { /// If the caller needs to know if it's readable, try to read the log instead with a reverse or forward iterator. pub fn log_exists(&self, store: &file::Store) -> bool { store - .reflog_exists(self.name.borrow()) + .reflog_exists(self.name.to_ref()) .expect("name conversion infallible") } /// 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 { store: &file::Store, buf: &'b mut [u8], ) -> std::io::Result>> { - store.reflog_iter_rev(self.name.borrow(), buf).map_err(must_be_io_err) + store.reflog_iter_rev(self.name.to_ref(), buf).map_err(must_be_io_err) } /// 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 { &'a self, store: &file::Store, buf: &'b mut Vec, - ) -> std::io::Result, log::iter::decode::Error>> + 'a>> { - store.reflog_iter(self.name.borrow(), buf).map_err(must_be_io_err) + ) -> std::io::Result, log::iter::decode::Error>> + 'a>> { + store.reflog_iter(self.name.to_ref(), buf).map_err(must_be_io_err) } } diff --git a/git-ref/src/store/file/loose/reference/peel.rs b/git-ref/src/store/file/loose/reference/peel.rs index be04267d8fb..70b00f91b46 100644 --- a/git-ref/src/store/file/loose/reference/peel.rs +++ b/git-ref/src/store/file/loose/reference/peel.rs @@ -2,11 +2,11 @@ use quick_error::quick_error; use crate::{ file, - mutable::Target, store::{ file::{find, loose}, packed, }, + Target, }; quick_error! { @@ -67,8 +67,8 @@ pub mod to_id { use quick_error::quick_error; use crate::{ - mutable::{FullName, Target}, store::{file, file::loose, packed}, + FullName, Target, }; quick_error! { diff --git a/git-ref/src/store/file/loose/reflog.rs b/git-ref/src/store/file/loose/reflog.rs index 4ed4a15183c..e602c1a263e 100644 --- a/git-ref/src/store/file/loose/reflog.rs +++ b/git-ref/src/store/file/loose/reflog.rs @@ -2,7 +2,7 @@ use std::{convert::TryInto, io::Read, path::PathBuf}; use crate::{ store::{file, file::log}, - FullName, + FullNameRef, }; impl file::Store { @@ -13,7 +13,7 @@ impl file::Store { /// If the caller needs to know if it's readable, try to read the log instead with a reverse or forward iterator. pub fn reflog_exists<'a, Name, E>(&self, name: Name) -> Result where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, crate::name::Error: From, { Ok(self.reflog_path(name.try_into()?).is_file()) @@ -29,10 +29,10 @@ impl file::Store { buf: &'b mut [u8], ) -> Result>, Error> where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, crate::name::Error: From, { - let name: FullName<'_> = name.try_into().map_err(|err| Error::RefnameValidation(err.into()))?; + let name: FullNameRef<'_> = name.try_into().map_err(|err| Error::RefnameValidation(err.into()))?; let path = self.reflog_path(name); if path.is_dir() { return Ok(None); @@ -52,12 +52,12 @@ impl file::Store { &self, name: Name, buf: &'b mut Vec, - ) -> Result, log::iter::decode::Error>>>, Error> + ) -> Result, log::iter::decode::Error>>>, Error> where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, crate::name::Error: From, { - let name: FullName<'_> = name.try_into().map_err(|err| Error::RefnameValidation(err.into()))?; + let name: FullNameRef<'_> = name.try_into().map_err(|err| Error::RefnameValidation(err.into()))?; let path = self.reflog_path(name); match std::fs::File::open(&path) { Ok(mut file) => { @@ -77,7 +77,7 @@ impl file::Store { impl file::Store { /// Implements the logic required to transform a fully qualified refname into its log name - pub(crate) fn reflog_path(&self, name: FullName<'_>) -> PathBuf { + pub(crate) fn reflog_path(&self, name: FullNameRef<'_>) -> PathBuf { self.reflog_path_inner(&name.to_path()) } } diff --git a/git-ref/src/store/file/loose/reflog/create_or_update/tests.rs b/git-ref/src/store/file/loose/reflog/create_or_update/tests.rs index 9fcb2bdd351..95389187b6b 100644 --- a/git-ref/src/store/file/loose/reflog/create_or_update/tests.rs +++ b/git-ref/src/store/file/loose/reflog/create_or_update/tests.rs @@ -1,5 +1,5 @@ use super::*; -use crate::{file::WriteReflog, store::file::log, FullName}; +use crate::{file::WriteReflog, store::file::log, FullNameRef}; use bstr::ByteSlice; use git_actor::{Sign, Signature, Time}; use git_lock::acquire::Fail; @@ -16,7 +16,7 @@ fn empty_store(writemode: WriteReflog) -> Result<(TempDir, file::Store)> { } fn reflock(store: &file::Store, full_name: &str) -> Result { - let full_name: FullName<'_> = full_name.try_into()?; + let full_name: FullNameRef<'_> = full_name.try_into()?; git_lock::Marker::acquire_to_hold_resource( store.reference_path(&full_name.to_path()), Fail::Immediately, @@ -25,11 +25,11 @@ fn reflock(store: &file::Store, full_name: &str) -> Result { .map_err(Into::into) } -fn reflog_lines(store: &file::Store, name: &str, buf: &mut Vec) -> Result> { +fn reflog_lines(store: &file::Store, name: &str, buf: &mut Vec) -> Result> { store .reflog_iter(name, buf)? .expect("existing reflog") - .map(|l| l.map(log::mutable::Line::from)) + .map(|l| l.map(log::Line::from)) .collect::, _>>() .map_err(Into::into) } @@ -83,7 +83,7 @@ fn missing_reflog_creates_it_even_if_similarly_named_empty_dir_exists_and_append WriteReflog::Normal => { assert_eq!( reflog_lines(&store, full_name, &mut buf)?, - vec![log::mutable::Line { + vec![log::Line { previous_oid: ObjectId::null_sha1(), new_oid: new, signature: committer.clone(), @@ -104,7 +104,7 @@ fn missing_reflog_creates_it_even_if_similarly_named_empty_dir_exists_and_append assert_eq!(lines.len(), 2, "now there is another line"); assert_eq!( lines.last().expect("non-empty"), - &log::mutable::Line { + &log::Line { previous_oid: previous, new_oid: new, signature: committer.clone(), diff --git a/git-ref/src/store/file/overlay.rs b/git-ref/src/store/file/overlay.rs index 2da877b83bf..f77805229e3 100644 --- a/git-ref/src/store/file/overlay.rs +++ b/git-ref/src/store/file/overlay.rs @@ -7,8 +7,8 @@ use std::{ use crate::{ file::{loose, path_to_name, Reference}, - mutable::FullName, store::{file, packed}, + FullName, }; /// An iterator stepping through sorted input of loose references and packed references, preferring loose refs over otherwise diff --git a/git-ref/src/store/file/reference.rs b/git-ref/src/store/file/reference.rs index 352f1cf7e90..3e5815f7db7 100644 --- a/git-ref/src/store/file/reference.rs +++ b/git-ref/src/store/file/reference.rs @@ -5,13 +5,12 @@ use git_hash::ObjectId; use crate::{ file::loose::reference::logiter::must_be_io_err, - mutable, store::{ file, file::{log, loose}, packed, }, - FullName, Namespace, + FullNameRef, Namespace, Target, }; /// Either a loose or packed reference, depending on where it was found. @@ -112,9 +111,9 @@ impl<'p> Reference<'p> { &'a self, store: &file::Store, buf: &'b mut Vec, - ) -> std::io::Result, log::iter::decode::Error>> + 'a>> { + ) -> std::io::Result, log::iter::decode::Error>> + 'a>> { match self { - Reference::Loose(r) => store.reflog_iter(r.name.borrow(), buf).map_err(must_be_io_err), + Reference::Loose(r) => store.reflog_iter(r.name.to_ref(), buf).map_err(must_be_io_err), Reference::Packed(p) => store.reflog_iter(p.name, buf).map_err(must_be_io_err), } } @@ -128,9 +127,9 @@ impl<'p> Reference<'p> { } /// Transform this reference into an owned `Target` - pub fn into_target(self) -> mutable::Target { + pub fn into_target(self) -> Target { match self { - Reference::Packed(p) => mutable::Target::Peeled(p.object()), + Reference::Packed(p) => Target::Peeled(p.object()), Reference::Loose(r) => r.target, } } @@ -144,28 +143,28 @@ impl<'p> Reference<'p> { } /// Return the full validated name of the reference, which may include a namespace. - pub fn name(&self) -> FullName<'_> { + pub fn name(&self) -> FullNameRef<'_> { match self { Reference::Packed(p) => p.name, - Reference::Loose(l) => l.name.borrow(), + Reference::Loose(l) => l.name.to_ref(), } } /// Return the full validated name of the reference, with the given namespace stripped if possible. /// /// If the reference name wasn't prefixed with `namespace`, `None` is returned instead. - pub fn name_without_namespace(&self, namespace: &Namespace) -> Option> { + pub fn name_without_namespace(&self, namespace: &Namespace) -> Option> { self.name() .0 .as_bstr() .strip_prefix(namespace.0.as_bstr().as_ref()) - .map(|stripped| FullName(stripped.as_bstr())) + .map(|stripped| FullNameRef(stripped.as_bstr())) } /// Return the target to which the reference points to. - pub fn target(&self) -> mutable::Target { + pub fn target(&self) -> Target { match self { - Reference::Packed(p) => mutable::Target::Peeled(p.target()), + Reference::Packed(p) => Target::Peeled(p.target()), Reference::Loose(l) => l.target.clone(), } } diff --git a/git-ref/src/store/file/transaction/commit.rs b/git-ref/src/store/file/transaction/commit.rs index 0bb963ecfda..5e149095491 100644 --- a/git-ref/src/store/file/transaction/commit.rs +++ b/git-ref/src/store/file/transaction/commit.rs @@ -1,7 +1,7 @@ use crate::{ - mutable::Target, store::file::{transaction::PackedRefs, Transaction}, transaction::{Change, LogChange, RefEdit, RefLog}, + Target, }; impl<'s> Transaction<'s> { @@ -102,7 +102,7 @@ impl<'s> Transaction<'s> { Change::Delete { .. } => { // Reflog deletion happens first in case it fails a ref without log is less terrible than // a log without a reference. - let reflog_path = self.store.reflog_path(change.update.name.borrow()); + let reflog_path = self.store.reflog_path(change.update.name.to_ref()); if let Err(err) = std::fs::remove_file(&reflog_path) { if err.kind() != std::io::ErrorKind::NotFound { return Err(Error::DeleteReflog { diff --git a/git-ref/src/store/file/transaction/prepare.rs b/git-ref/src/store/file/transaction/prepare.rs index 0a4bedb78c0..4f0c5e5ebce 100644 --- a/git-ref/src/store/file/transaction/prepare.rs +++ b/git-ref/src/store/file/transaction/prepare.rs @@ -1,5 +1,4 @@ use crate::{ - mutable::Target, packed, store::{ file, @@ -10,6 +9,7 @@ use crate::{ }, }, transaction::{Change, Create, LogChange, RefEdit, RefEditsExt, RefLog}, + Target, }; impl<'s> Transaction<'s> { @@ -44,7 +44,7 @@ impl<'s> Transaction<'s> { }) .and_then(|maybe_loose| match (maybe_loose, packed) { (None, Some(packed)) => packed - .find(change.update.name.borrow()) + .find(change.update.name.to_ref()) .map(|opt| opt.map(file::Reference::Packed)) .map_err(Error::from), (None, None) => Ok(None), @@ -104,7 +104,7 @@ impl<'s> Transaction<'s> { let existing_ref = existing_ref?; match (&previous, &existing_ref) { - (Create::Only, Some(existing)) if existing.target() != new.borrow() => { + (Create::Only, Some(existing)) if existing.target() != new.to_ref() => { let new = new.clone(); return Err(Error::MustNotExist { full_name: change.name(), @@ -321,7 +321,7 @@ impl<'s> Transaction<'s> { // traverse parent chain from leaf/peeled ref and set the leaf previous oid accordingly // to help with their reflog entries - if let (Some(crate::Target::Peeled(oid)), Some(parent_idx)) = + if let (Some(crate::TargetRef::Peeled(oid)), Some(parent_idx)) = (change.update.change.previous_value(), change.parent_index) { let oid = oid.to_owned(); @@ -342,8 +342,8 @@ mod error { use quick_error::quick_error; use crate::{ - mutable::Target, store::{file, packed}, + Target, }; quick_error! { diff --git a/git-ref/src/store/packed/decode.rs b/git-ref/src/store/packed/decode.rs index 01a34d4921a..10d91f154e0 100644 --- a/git-ref/src/store/packed/decode.rs +++ b/git-ref/src/store/packed/decode.rs @@ -73,7 +73,7 @@ pub fn reference<'a, E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], crate ) -> IResult<&'a [u8], packed::Reference<'a>, E> { let (input, (target, name)) = tuple(( terminated(hex_hash, tag(b" ")), - map_res(until_newline, crate::FullName::try_from), + map_res(until_newline, crate::FullNameRef::try_from), ))(input)?; let (rest, object) = opt(delimited(tag(b"^"), hex_hash, newline))(input)?; Ok((rest, packed::Reference { name, target, object })) diff --git a/git-ref/src/store/packed/decode/tests.rs b/git-ref/src/store/packed/decode/tests.rs index bd163366f90..7fb4443a239 100644 --- a/git-ref/src/store/packed/decode/tests.rs +++ b/git-ref/src/store/packed/decode/tests.rs @@ -7,7 +7,7 @@ mod reference { use super::Result; use crate::{ store::{packed, packed::decode}, - FullName, + FullNameRef, }; #[test] @@ -28,7 +28,7 @@ mod reference { assert_eq!( parsed, packed::Reference { - name: FullName("refs/heads/alternates-after-packs-and-loose".into()), + name: FullNameRef("refs/heads/alternates-after-packs-and-loose".into()), target: "d53c4b0f91f1b29769c9430f2d1c0bcab1170c75".into(), object: Some("e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37".into()) } @@ -38,7 +38,7 @@ mod reference { let (input, parsed) = decode::reference::>(input)?; assert!(input.is_empty(), "exhausted"); - assert_eq!(parsed.name, FullName("refs/heads/avoid-double-lookup".into())); + assert_eq!(parsed.name, FullNameRef("refs/heads/avoid-double-lookup".into())); assert_eq!(parsed.target, "eaae9c1bc723209d793eb93f5587fa2604d5cd92"); assert!(parsed.object.is_none()); Ok(()) diff --git a/git-ref/src/store/packed/find.rs b/git-ref/src/store/packed/find.rs index d9f9af19f42..433fdcda662 100644 --- a/git-ref/src/store/packed/find.rs +++ b/git-ref/src/store/packed/find.rs @@ -2,14 +2,14 @@ use std::{borrow::Cow, convert::TryInto}; use bstr::{BStr, BString, ByteSlice}; -use crate::{store::packed, PartialName}; +use crate::{store::packed, PartialNameRef}; /// packed-refs specific functionality impl packed::Buffer { /// Find a reference with the given `name` and return it. pub fn find<'a, Name, E>(&self, name: Name) -> Result>, Error> where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, Error: From, { let name = name.try_into()?; @@ -54,7 +54,7 @@ impl packed::Buffer { /// Find a reference with the given `name` and return it. pub fn find_existing<'a, Name, E>(&self, name: Name) -> Result, existing::Error> where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, Error: From, { match self.find(name) { diff --git a/git-ref/src/store/packed/mod.rs b/git-ref/src/store/packed/mod.rs index 75bf30af2eb..a3d7bc60278 100644 --- a/git-ref/src/store/packed/mod.rs +++ b/git-ref/src/store/packed/mod.rs @@ -4,7 +4,7 @@ use bstr::{BStr, BString}; use filebuffer::FileBuffer; use git_hash::ObjectId; -use crate::{transaction::RefEdit, FullName}; +use crate::{transaction::RefEdit, FullNameRef}; enum Backing { /// 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 { #[derive(Debug, PartialEq, Eq)] pub struct Reference<'a> { /// The validated full name of the reference. - pub name: FullName<'a>, + pub name: FullNameRef<'a>, /// The target object id of the reference, hex encoded. pub target: &'a BStr, /// The fully peeled object id, hex encoded, that the ref is ultimately pointing to diff --git a/git-ref/src/store/packed/transaction.rs b/git-ref/src/store/packed/transaction.rs index 212ce1296da..f578fcf1bf4 100644 --- a/git-ref/src/store/packed/transaction.rs +++ b/git-ref/src/store/packed/transaction.rs @@ -1,9 +1,9 @@ use std::io::Write; use crate::{ - mutable::Target, store::{file::transaction::FindObjectFn, packed, packed::Edit}, transaction::{Change, RefEdit}, + Target, }; pub(crate) const HEADER_LINE: &[u8] = b"# pack-refs with: peeled fully-peeled sorted \n"; @@ -56,7 +56,7 @@ impl packed::Transaction { if let Change::Delete { .. } = edit.change { buffer .as_ref() - .map_or(true, |b| b.find_existing(edit.name.borrow()).is_ok()) + .map_or(true, |b| b.find_existing(edit.name.to_ref()).is_ok()) } else { true } diff --git a/git-ref/src/target.rs b/git-ref/src/target.rs index 0a825f62965..c24dce50936 100644 --- a/git-ref/src/target.rs +++ b/git-ref/src/target.rs @@ -1,9 +1,38 @@ -use bstr::BStr; -use git_hash::oid; +use bstr::{BStr, ByteSlice}; +use git_hash::{oid, ObjectId}; +use std::fmt; -use crate::{Kind, Target}; +use crate::{FullName, Kind, Target, TargetRef}; -impl<'a> Target<'a> { +impl<'a> TargetRef<'a> { + /// Returns the kind of the target the ref is pointing to. + pub fn kind(&self) -> Kind { + match self { + TargetRef::Symbolic(_) => Kind::Symbolic, + TargetRef::Peeled(_) => Kind::Peeled, + } + } + /// Interpret this target as object id which maybe `None` if it is symbolic. + pub fn as_id(&self) -> Option<&oid> { + match self { + TargetRef::Symbolic(_) => None, + TargetRef::Peeled(oid) => Some(oid), + } + } + /// Interpret this target as name of the reference it points to which maybe `None` if it an object id. + pub fn as_name(&self) -> Option<&BStr> { + match self { + TargetRef::Symbolic(path) => Some(path), + TargetRef::Peeled(_) => None, + } + } + /// Convert this instance into an owned version, without consuming it. + pub fn into_owned(self) -> crate::Target { + self.into() + } +} + +impl Target { /// Returns the kind of the target the ref is pointing to. pub fn kind(&self) -> Kind { match self { @@ -11,6 +40,23 @@ impl<'a> Target<'a> { Target::Peeled(_) => Kind::Peeled, } } + + /// Return true if this is a peeled target with a null hash + pub fn is_null(&self) -> bool { + match self { + Target::Peeled(oid) => oid.is_null(), + Target::Symbolic(_) => false, + } + } + + /// Interpret this owned Target as shared Target + pub fn to_ref(&self) -> crate::TargetRef<'_> { + match self { + Target::Peeled(oid) => crate::TargetRef::Peeled(oid), + Target::Symbolic(name) => crate::TargetRef::Symbolic(name.0.as_bstr()), + } + } + /// Interpret this target as object id which maybe `None` if it is symbolic. pub fn as_id(&self) -> Option<&oid> { match self { @@ -21,12 +67,41 @@ impl<'a> Target<'a> { /// Interpret this target as name of the reference it points to which maybe `None` if it an object id. pub fn as_name(&self) -> Option<&BStr> { match self { - Target::Symbolic(path) => Some(path), + Target::Symbolic(name) => Some(name.as_bstr()), Target::Peeled(_) => None, } } - /// Convert this instance into an owned version, without consuming it. - pub fn to_owned(self) -> crate::mutable::Target { - self.into() + + /// Create an instance that signals that a reference should exist if this value is used in a [`Change`][crate::transaction::Change]. + pub fn must_exist() -> Self { + Target::Peeled(ObjectId::null_sha1()) + } +} + +impl<'a> From> for Target { + fn from(src: crate::TargetRef<'a>) -> Self { + match src { + crate::TargetRef::Peeled(oid) => Target::Peeled(oid.to_owned()), + crate::TargetRef::Symbolic(name) => Target::Symbolic(FullName(name.to_owned())), + } + } +} + +impl<'a> PartialEq> for Target { + fn eq(&self, other: &crate::TargetRef<'a>) -> bool { + match (self, other) { + (Target::Peeled(lhs), crate::TargetRef::Peeled(rhs)) => lhs == rhs, + (Target::Symbolic(lhs), crate::TargetRef::Symbolic(rhs)) => lhs.as_bstr() == *rhs, + _ => false, + } + } +} + +impl fmt::Display for Target { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Target::Peeled(oid) => oid.fmt(f), + Target::Symbolic(name) => write!(f, "ref: {}", name.as_bstr()), + } } } diff --git a/git-ref/src/transaction.rs b/git-ref/src/transaction.rs index 2e11c3c9e82..c3c459811d8 100644 --- a/git-ref/src/transaction.rs +++ b/git-ref/src/transaction.rs @@ -15,7 +15,7 @@ use bstr::BString; use git_hash::ObjectId; -use crate::mutable::{FullName, Target}; +use crate::{FullName, Target}; /// A change to the reflog. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] @@ -101,14 +101,14 @@ pub enum Change { impl Change { /// Return references to values that are in common between all variants. - pub fn previous_value(&self) -> Option> { + pub fn previous_value(&self) -> Option> { match self { Change::Update { mode: Create::Only, .. } => None, Change::Update { mode: Create::OrUpdate { previous }, .. } - | Change::Delete { previous, .. } => previous.as_ref().map(|t| t.borrow()), + | Change::Delete { previous, .. } => previous.as_ref().map(|t| t.to_ref()), } } } @@ -139,7 +139,7 @@ mod ext { use crate::{ transaction::{Change, LogChange, RefEdit, RefLog, Target}, - Namespace, PartialName, + Namespace, PartialNameRef, }; /// An extension trait to perform commonly used operations on edits across different ref stores. @@ -155,7 +155,7 @@ mod ext { /// Note no action is performed if deref isn't specified. fn extend_with_splits_of_symbolic_refs( &mut self, - find: impl FnMut(PartialName<'_>) -> Option, + find: impl FnMut(PartialNameRef<'_>) -> Option, make_entry: impl FnMut(usize, RefEdit) -> T, ) -> Result<(), std::io::Error>; @@ -168,7 +168,7 @@ mod ext { /// Users call this to assure derefs are honored and duplicate checks are done. fn pre_process( &mut self, - find: impl FnMut(PartialName<'_>) -> Option, + find: impl FnMut(PartialNameRef<'_>) -> Option, make_entry: impl FnMut(usize, RefEdit) -> T, namespace: impl Into>, ) -> Result<(), std::io::Error> { @@ -198,7 +198,7 @@ mod ext { fn extend_with_splits_of_symbolic_refs( &mut self, - mut find: impl FnMut(PartialName<'_>) -> Option, + mut find: impl FnMut(PartialNameRef<'_>) -> Option, mut make_entry: impl FnMut(usize, RefEdit) -> E, ) -> Result<(), std::io::Error> { let mut new_edits = Vec::new(); diff --git a/git-ref/tests/file/log.rs b/git-ref/tests/file/log.rs index 8c0d1a5b97c..6f1af0a80d2 100644 --- a/git-ref/tests/file/log.rs +++ b/git-ref/tests/file/log.rs @@ -6,7 +6,7 @@ mod line { #[test] fn newlines_in_message_of_the_input_fails_and_we_trust_signature_writing_validation() -> crate::Result { let line = "0000000000000000000000000000000000000000 134385f6d781b7e97062102c6a483440bfda2a03 committer 946771200 +0000 commit (initial): c1"; - let mut line = log::Line::from_bytes(line.as_bytes())?.to_mutable(); + let mut line = log::LineRef::from_bytes(line.as_bytes())?.to_owned(); line.message.push_str("and here come\nthe newline"); let err = line .write_to(&mut Vec::new()) @@ -20,10 +20,10 @@ mod line { let lines = &["0000000000000000000000000000000000000000 134385f6d781b7e97062102c6a483440bfda2a03 committer 946771200 +0000 commit (initial): c1\n", "0000000000000000000000000000000000000000 134385f6d781b7e97062102c6a483440bfda2a03 committer 946771200 +0000 \n"]; for line in lines { - let line = log::Line::from_bytes(line.as_bytes())?; + let line = log::LineRef::from_bytes(line.as_bytes())?; let mut buf = Vec::new(); - line.to_mutable().write_to(&mut buf)?; - let same_line = log::Line::from_bytes(&buf)?; + line.to_owned().write_to(&mut buf)?; + let same_line = log::LineRef::from_bytes(&buf)?; assert_eq!(line, same_line); } Ok(()) @@ -75,7 +75,7 @@ mod iter { } mod with_buffer_big_enough_for_largest_line { - use git_ref::file::log::mutable::Line; + use git_ref::file::log::Line; use git_testtools::hex_to_id; #[test] diff --git a/git-ref/tests/file/reference.rs b/git-ref/tests/file/reference.rs index bc407557052..c338021bbdd 100644 --- a/git-ref/tests/file/reference.rs +++ b/git-ref/tests/file/reference.rs @@ -68,13 +68,13 @@ mod peel { ) .expect("loose ref"); assert!( - matches!(nr.target.borrow(), git_ref::Target::Peeled(_)), + matches!(nr.target.to_ref(), git_ref::TargetRef::Peeled(_)), "iteration peels a single level" ); assert!(nr.follow_symbolic(&store, None).is_none(), "end of iteration"); assert_eq!( - nr.target.borrow(), - git_ref::Target::Peeled(&hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03")), + nr.target.to_ref(), + git_ref::TargetRef::Peeled(&hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03")), "we still have the peeled target" ); Ok(()) @@ -203,8 +203,8 @@ mod parse { let reference = Reference::try_from_path("HEAD".try_into().expect("valid static name"), $input).unwrap(); assert_eq!(reference.kind(), $kind); - assert_eq!(reference.target.borrow().as_id(), $id); - assert_eq!(reference.target.borrow().as_name(), $ref); + assert_eq!(reference.target.to_ref().as_id(), $id); + assert_eq!(reference.target.to_ref().as_name(), $ref); } }; } diff --git a/git-ref/tests/file/store/find.rs b/git-ref/tests/file/store/find.rs index c4ebb4faa7b..6ced5e3b4f4 100644 --- a/git-ref/tests/file/store/find.rs +++ b/git-ref/tests/file/store/find.rs @@ -9,7 +9,7 @@ mod existing { let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); let packed = store.packed_buffer()?; let r = store.find_existing("main", packed.as_ref())?; - assert_eq!(r.target().borrow().as_id().expect("peeled"), c1); + assert_eq!(r.target().to_ref().as_id().expect("peeled"), c1); assert_eq!(r.name().as_bstr(), "refs/heads/main"); Ok(()) } @@ -62,7 +62,7 @@ mod loose { ] { let reference = store.loose_find(*partial_name)?.expect("exists"); assert_eq!(reference.name.as_bstr(), expected_path); - assert_eq!(reference.target.borrow().kind(), *expected_ref_kind); + assert_eq!(reference.target.to_ref().kind(), *expected_ref_kind); } Ok(()) } diff --git a/git-ref/tests/file/store/iter.rs b/git-ref/tests/file/store/iter.rs index aa91b53eafb..ce46c3cd8bd 100644 --- a/git-ref/tests/file/store/iter.rs +++ b/git-ref/tests/file/store/iter.rs @@ -202,7 +202,7 @@ fn loose_iter_with_prefix() -> crate::Result { #[test] fn overlay_iter() -> crate::Result { - use git_ref::mutable::Target::*; + use git_ref::Target::*; let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store @@ -249,7 +249,7 @@ fn overlay_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result { #[test] fn overlay_prefixed_iter() -> crate::Result { - use git_ref::mutable::Target::*; + use git_ref::Target::*; let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let ref_names = store diff --git a/git-ref/tests/file/transaction/mod.rs b/git-ref/tests/file/transaction/mod.rs index 8d37b692765..29b01c83249 100644 --- a/git-ref/tests/file/transaction/mod.rs +++ b/git-ref/tests/file/transaction/mod.rs @@ -1,15 +1,16 @@ mod prepare_and_commit { use bstr::BString; + use git_actor::{Sign, Time}; use git_hash::ObjectId; - use git_ref::{file, file::log}; + use git_ref::file; - fn reflog_lines(store: &file::Store, name: &str) -> crate::Result> { + fn reflog_lines(store: &file::Store, name: &str) -> crate::Result> { let mut buf = Vec::new(); let res = store .reflog_iter(name, &mut buf)? .expect("existing reflog") - .map(|l| l.map(log::mutable::Line::from)) + .map(|l| l.map(file::log::Line::from)) .collect::, _>>()?; Ok(res) } @@ -32,8 +33,8 @@ mod prepare_and_commit { } } - fn log_line(previous: ObjectId, new: ObjectId, message: impl Into) -> log::mutable::Line { - log::mutable::Line { + fn log_line(previous: ObjectId, new: ObjectId, message: impl Into) -> file::log::Line { + file::log::Line { previous_oid: previous, new_oid: new, signature: committer(), diff --git a/git-ref/tests/file/transaction/prepare_and_commit/create_or_update.rs b/git-ref/tests/file/transaction/prepare_and_commit/create_or_update.rs index 43bde86beae..97c5277d5fd 100644 --- a/git-ref/tests/file/transaction/prepare_and_commit/create_or_update.rs +++ b/git-ref/tests/file/transaction/prepare_and_commit/create_or_update.rs @@ -11,8 +11,8 @@ use git_ref::{ transaction::{self, PackedRefs}, WriteReflog, }, - mutable::Target, transaction::{Change, Create, LogChange, RefEdit, RefLog}, + Target, }; use git_testtools::hex_to_id; use std::convert::TryInto; @@ -328,7 +328,7 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { let head = store.loose_find_existing(edits[0].name.to_partial())?; assert_eq!(head.name.as_bstr(), "HEAD"); assert_eq!(head.kind(), git_ref::Kind::Symbolic); - assert_eq!(head.target.borrow().as_name(), Some(referent.as_bytes().as_bstr())); + assert_eq!(head.target.to_ref().as_name(), Some(referent.as_bytes().as_bstr())); assert!(!head.log_exists(&store), "no reflog is written for symbolic ref"); assert!(store.loose_find(referent)?.is_none(), "referent wasn't created"); @@ -393,7 +393,7 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { "head is still symbolic, not detached" ); assert_eq!( - head.target.borrow().as_name(), + head.target.to_ref().as_name(), Some(referent.as_bytes().as_bstr()), "it still points to the referent" ); @@ -401,7 +401,7 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { let referent_ref = store.loose_find_existing(referent)?; assert_eq!(referent_ref.kind(), git_ref::Kind::Peeled, "referent is a peeled ref"); assert_eq!( - referent_ref.target.borrow().as_id(), + referent_ref.target.to_ref().as_id(), Some(new_oid.as_ref()), "referent points to desired hash" ); @@ -431,7 +431,7 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { fn write_reference_to_which_head_points_to_does_not_update_heads_reflog_even_though_it_should() -> crate::Result { let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; let head = store.loose_find_existing("HEAD")?; - let referent = head.target.borrow().as_name().expect("symbolic ref").to_owned(); + let referent = head.target.to_ref().as_name().expect("symbolic ref").to_owned(); let previous_head_reflog = reflog_lines(&store, "HEAD")?; let new_id = hex_to_id("01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc"); diff --git a/git-ref/tests/file/transaction/prepare_and_commit/delete.rs b/git-ref/tests/file/transaction/prepare_and_commit/delete.rs index 31cb9d99c1a..62622a407f9 100644 --- a/git-ref/tests/file/transaction/prepare_and_commit/delete.rs +++ b/git-ref/tests/file/transaction/prepare_and_commit/delete.rs @@ -4,8 +4,8 @@ use crate::file::{ }; use git_lock::acquire::Fail; use git_ref::{ - mutable::Target, transaction::{Change, RefEdit, RefLog}, + Target, }; use git_testtools::hex_to_id; use std::convert::TryInto; diff --git a/git-ref/tests/packed/find.rs b/git-ref/tests/packed/find.rs index ec7f2d19438..db138e08500 100644 --- a/git-ref/tests/packed/find.rs +++ b/git-ref/tests/packed/find.rs @@ -1,6 +1,6 @@ use std::convert::{TryFrom, TryInto}; -use git_ref::{packed, PartialName}; +use git_ref::{packed, PartialNameRef}; use git_testtools::fixture_path; use crate::{ @@ -11,7 +11,7 @@ use crate::{ #[test] fn a_lock_file_would_not_be_a_valid_partial_name() { // doesn't really belong here but want to make sure refname validation works as expected. - let err = PartialName::try_from("heads/hello.lock").expect_err("this should fail"); + let err = PartialNameRef::try_from("heads/hello.lock").expect_err("this should fail"); assert_eq!(err.to_string(), "A reference must be a valid tag name as well"); } diff --git a/git-ref/tests/transaction/mod.rs b/git-ref/tests/transaction/mod.rs index f2692c1450d..e2443d17596 100644 --- a/git-ref/tests/transaction/mod.rs +++ b/git-ref/tests/transaction/mod.rs @@ -3,9 +3,8 @@ mod refedit_ext { use bstr::{BString, ByteSlice}; use git_ref::{ - mutable::Target, transaction::{Change, Create, RefEdit, RefEditsExt, RefLog}, - PartialName, + PartialNameRef, Target, }; #[derive(Default)] @@ -26,7 +25,7 @@ mod refedit_ext { }, } } - fn find_existing(&self, name: PartialName<'_>) -> Option { + fn find_existing(&self, name: PartialNameRef<'_>) -> Option { self.targets.borrow_mut().remove(name.as_bstr()) } } @@ -149,16 +148,15 @@ mod refedit_ext { use git_hash::ObjectId; use git_ref::{ - mutable::Target, transaction::{Change, Create, LogChange, RefEdit, RefEditsExt, RefLog}, - FullName, PartialName, + FullNameRef, PartialNameRef, Target, }; use git_testtools::hex_to_id; use crate::transaction::refedit_ext::MockStore; fn find<'a>(edits: &'a [RefEdit], name: &str) -> &'a RefEdit { - let name: FullName = name.try_into().unwrap(); + let name: FullNameRef = name.try_into().unwrap(); edits .iter() .find(|e| e.name.as_bstr() == name.as_bstr()) @@ -229,7 +227,7 @@ mod refedit_ext { next_item: Cell, } impl Cycler { - fn find_existing(&self, _name: PartialName<'_>) -> Option { + fn find_existing(&self, _name: PartialNameRef<'_>) -> Option { let item: bool = self.next_item.get(); self.next_item.set(!item); Some(Target::Symbolic( diff --git a/git-repository/Cargo.toml b/git-repository/Cargo.toml index bcdd5ac41e1..b80b91c7c53 100644 --- a/git-repository/Cargo.toml +++ b/git-repository/Cargo.toml @@ -42,7 +42,7 @@ git-validate = { version = "^0.5.0", path = "../git-validate" } git-odb = { version ="0.20.0", path = "../git-odb" } git-hash = { version = "^0.5.0", path = "../git-hash" } git-object = { version ="0.12.0", path = "../git-object" } -git-actor = { version ="^0.4.0", path = "../git-actor" } +git-actor = { version ="^0.5.0", path = "../git-actor" } git-pack = { version ="^0.9.0", path = "../git-pack" } git-url = { version = "0.3.0", path = "../git-url", optional = true } diff --git a/git-repository/src/easy/ext/reference.rs b/git-repository/src/easy/ext/reference.rs index df9e06d6d57..52ae1651f0c 100644 --- a/git-repository/src/easy/ext/reference.rs +++ b/git-repository/src/easy/ext/reference.rs @@ -10,9 +10,8 @@ use git_actor as actor; use git_lock as lock; use git_ref::{ file::find::Error, - mutable::Target, transaction::{Change, Create, RefEdit}, - PartialName, + PartialNameRef, Target, }; /// Obtain and alter references comfortably @@ -77,7 +76,7 @@ pub trait ReferenceAccessExt: easy::Access + Sized { fn find_reference<'a, Name, E>(&self, name: Name) -> Result, reference::find::existing::Error> where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, Error: From, { self.try_find_reference(name)? @@ -86,7 +85,7 @@ pub trait ReferenceAccessExt: easy::Access + Sized { fn try_find_reference<'a, Name, E>(&self, name: Name) -> Result>, reference::find::Error> where - Name: TryInto, Error = E>, + Name: TryInto, Error = E>, Error: From, { let state = self.state(); diff --git a/git-repository/src/easy/reference.rs b/git-repository/src/easy/reference.rs index 46a0e848907..0dcd1b89ef8 100644 --- a/git-repository/src/easy/reference.rs +++ b/git-repository/src/easy/reference.rs @@ -12,7 +12,7 @@ use git_ref as refs; pub(crate) enum Backing { OwnedPacked { /// The validated full name of the reference. - name: refs::mutable::FullName, + name: refs::FullName, /// The target object id of the reference, hex encoded. target: ObjectId, /// The fully peeled object id, hex encoded, that the ref is ultimately pointing to @@ -107,19 +107,19 @@ where access, } } - pub fn target(&self) -> refs::mutable::Target { + pub fn target(&self) -> refs::Target { match self.backing.as_ref().expect("always set") { - Backing::OwnedPacked { target, .. } => refs::mutable::Target::Peeled(target.to_owned()), + Backing::OwnedPacked { target, .. } => refs::Target::Peeled(target.to_owned()), Backing::LooseFile(r) => r.target.clone(), } } - pub fn name(&self) -> refs::FullName<'_> { + pub fn name(&self) -> refs::FullNameRef<'_> { match self.backing.as_ref().expect("always set") { Backing::OwnedPacked { name, .. } => name, Backing::LooseFile(r) => &r.name, } - .borrow() + .to_ref() } pub fn peel_to_oid_in_place(&mut self) -> Result, peel_to_oid_in_place::Error> { diff --git a/git-repository/tests/reference/mod.rs b/git-repository/tests/reference/mod.rs index 1917777b028..c0a7031690c 100644 --- a/git-repository/tests/reference/mod.rs +++ b/git-repository/tests/reference/mod.rs @@ -19,7 +19,7 @@ mod find { assert_eq!( packed_tag_ref.target(), - refs::mutable::Target::Peeled(hex_to_id("4c3f4cce493d7beb45012e478021b5f65295e5a3")), + refs::Target::Peeled(hex_to_id("4c3f4cce493d7beb45012e478021b5f65295e5a3")), "it points to a tag object" );