Showing the changes to git-ref/src (4 of 4 files). Show all
Unified · Split
| @@ -28,11 +28,11 @@ impl file::Store { · 27 unmodified lines | ||
| 28 | 28 | /// The lookup algorithm follows the one in [the git documentation][git-lookup-docs]. |
| 29 | 29 | /// |
| 30 | 30 | /// [git-lookup-docs]: https://github.com/git/git/blob/5d5b1473453400224ebb126bf3947e0a3276bdf5/Documentation/revisions.txt#L34-L46 |
| 31 | − pub fn find<'a, 'p, Name, E>( | |
| 32 | − &self, | |
| 31 | + pub fn find<'a, 'p, 's, Name, E>( | |
| 32 | + &'s self, | |
| 33 | 33 | partial: Name, |
| 34 | 34 | packed: Option<&'p packed::Buffer>, |
| 35 | − ) -> Result<Option<file::Reference<'_>>, Error> | |
| 35 | + ) -> Result<Option<file::loose_then_packed::Reference<'p, 's>>, Error> | |
| 36 | 36 | where |
| 37 | 37 | Name: TryInto<PartialName<'a>, Error = E>, |
| 38 | 38 | Error: From<E>, |
| @@ -41,11 +41,11 @@ impl file::Store { · 2 unmodified lines | ||
| 41 | 41 | self.find_one_with_verified_input(path.to_partial_path().as_ref(), packed) |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | − pub(in crate::store::file) fn find_one_with_verified_input<'p>( | |
| 45 | − &self, | |
| 44 | + pub(in crate::store::file) fn find_one_with_verified_input<'p, 's>( | |
| 45 | + &'s self, | |
| 46 | 46 | relative_path: &Path, |
| 47 | 47 | packed: Option<&'p packed::Buffer>, |
| 48 | − ) -> Result<Option<file::Reference<'_>>, Error> { | |
| 48 | + ) -> Result<Option<file::loose_then_packed::Reference<'p, 's>>, Error> { | |
| 49 | 49 | let is_all_uppercase = relative_path |
| 50 | 50 | .to_string_lossy() |
| 51 | 51 | .as_ref() |
| @@ -74,13 +74,13 @@ impl file::Store { · 22 unmodified lines | ||
| 74 | 74 | ) |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | − fn find_inner<'p>( | |
| 78 | − &self, | |
| 77 | + fn find_inner<'p, 's>( | |
| 78 | + &'s self, | |
| 79 | 79 | inbetween: &str, |
| 80 | 80 | relative_path: &Path, |
| 81 | 81 | packed: Option<&'p packed::Buffer>, |
| 82 | 82 | transform: Transform, |
| 83 | − ) -> Result<Option<file::Reference<'_>>, Error> { | |
| 83 | + ) -> Result<Option<file::loose_then_packed::Reference<'p, 's>>, Error> { | |
| 84 | 84 | let (base, is_definitely_absolute) = match transform { |
| 85 | 85 | Transform::EnforceRefsPrefix => ( |
| 86 | 86 | if relative_path.starts_with("refs") { |
| @@ -100,8 +100,8 @@ impl file::Store { · 13 unmodified lines | ||
| 100 | 100 | if let Some(packed) = packed { |
| 101 | 101 | let full_name = path_to_name(relative_path); |
| 102 | 102 | let full_name = PartialName((*full_name).as_bstr()); |
| 103 | − if let Some(_packed_ref) = packed.find(full_name)? { | |
| 104 | − todo!("transform packed ref into standard ref") | |
| 103 | + if let Some(packed_ref) = packed.find(full_name)? { | |
| 104 | + return Ok(Some(file::loose_then_packed::Reference::Packed(packed_ref))); | |
| 105 | 105 | }; |
| 106 | 106 | } |
| 107 | 107 | } |
| @@ -111,6 +111,7 @@ impl file::Store { · 3 unmodified lines | ||
| 111 | 111 | }; |
| 112 | 112 | Ok(Some( |
| 113 | 113 | file::Reference::try_from_path(self, &relative_path, &contents) |
| 114 | + .map(file::loose_then_packed::Reference::Loose) | |
| 114 | 115 | .map_err(|err| Error::ReferenceCreation { err, relative_path })?, |
| 115 | 116 | )) |
| 116 | 117 | } |
| @@ -153,11 +154,11 @@ pub mod existing { · 36 unmodified lines | ||
| 153 | 154 | |
| 154 | 155 | impl file::Store { |
| 155 | 156 | /// Similar to [`file::Store::find()`] but a non-existing ref is treated as error. |
| 156 | − pub fn find_existing<'a, 'p, Name, E>( | |
| 157 | − &self, | |
| 157 | + pub fn find_existing<'a, 'p, 's, Name, E>( | |
| 158 | + &'s self, | |
| 158 | 159 | partial: Name, |
| 159 | 160 | packed: Option<&'p packed::Buffer>, |
| 160 | − ) -> Result<file::Reference<'_>, Error> | |
| 161 | + ) -> Result<file::loose_then_packed::Reference<'p, 's>, Error> | |
| 161 | 162 | where |
| 162 | 163 | Name: TryInto<PartialName<'a>, Error = E>, |
| 163 | 164 | crate::name::Error: From<E>, |
| @@ -32,6 +32,22 @@ pub enum Reference<'p, 's> { · 31 unmodified lines | ||
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | impl<'p, 's> Reference<'p, 's> { |
| 35 | + /// Returns the kind of reference | |
| 36 | + pub fn kind(&self) -> crate::Kind { | |
| 37 | + match self { | |
| 38 | + Reference::Loose(r) => r.kind(), | |
| 39 | + Reference::Packed(_) => crate::Kind::Peeled, | |
| 40 | + } | |
| 41 | + } | |
| 42 | + | |
| 43 | + /// Transform this reference into an owned `Target` | |
| 44 | + pub fn into_target(self) -> mutable::Target { | |
| 45 | + match self { | |
| 46 | + Reference::Packed(p) => mutable::Target::Peeled(p.object()), | |
| 47 | + Reference::Loose(r) => r.into_target(), | |
| 48 | + } | |
| 49 | + } | |
| 50 | + | |
| 35 | 51 | /// Returns true if this ref is located in a packed ref buffer. |
| 36 | 52 | pub fn is_packed(&self) -> bool { |
| 37 | 53 | match self { |
| @@ -5,6 +5,7 @@ use std::path::{Path, PathBuf}; · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | #[derive(Debug, PartialOrd, PartialEq, Ord, Eq, Hash, Clone)] |
| 7 | 7 | #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] |
| 8 | +// TODO: replace with usage of Target, which is the same but with better typing | |
| 8 | 9 | pub(in crate::file) enum State { |
| 9 | 10 | Id(ObjectId), |
| 10 | 11 | ValidatedPath(BString), |
| @@ -21,11 +21,14 @@ quick_error! { · 20 unmodified lines | ||
| 21 | 21 | } |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | −impl<'a> Reference<'a> { | |
| 24 | +impl<'s> Reference<'s> { | |
| 25 | 25 | /// Follow this symbolic reference one level and return the ref it refers to, possibly providing access to `packed` references for lookup. |
| 26 | 26 | /// |
| 27 | 27 | /// Returns `None` if this is not a symbolic reference, hence the leaf of the chain. |
| 28 | − pub fn peel_one_level(&self, packed: Option<&packed::Buffer>) -> Option<Result<Reference<'a>, Error>> { | |
| 28 | + pub fn peel_one_level<'p>( | |
| 29 | + &self, | |
| 30 | + packed: Option<&'p packed::Buffer>, | |
| 31 | + ) -> Option<Result<file::loose_then_packed::Reference<'p, 's>, Error>> { | |
| 29 | 32 | match &self.state { |
| 30 | 33 | State::Id(_) => None, |
| 31 | 34 | State::ValidatedPath(relative_path) => { |
| @@ -46,7 +49,7 @@ impl<'a> Reference<'a> { · 14 unmodified lines | ||
| 46 | 49 | pub mod to_id { |
| 47 | 50 | use crate::{ |
| 48 | 51 | file::{reference, Reference}, |
| 49 | − store::packed, | |
| 52 | + store::{file::loose_then_packed, packed}, | |
| 50 | 53 | }; |
| 51 | 54 | use git_hash::oid; |
| 52 | 55 | use quick_error::quick_error; |
| @@ -84,11 +87,17 @@ pub mod to_id { · 31 unmodified lines | ||
| 84 | 87 | while let Some(next) = cursor.peel_one_level(packed) { |
| 85 | 88 | let next_ref = next?; |
| 86 | 89 | if let crate::Kind::Peeled = next_ref.kind() { |
| 87 | − *self = next_ref; | |
| 90 | + match next_ref { | |
| 91 | + loose_then_packed::Reference::Loose(r) => *self = r, | |
| 92 | + loose_then_packed::Reference::Packed(_p) => todo!("assign state directly and convert path"), | |
| 93 | + }; | |
| 88 | 94 | return Ok(self.state.as_id().expect("it to be present")); |
| 89 | 95 | } |
| 90 | 96 | storage = next_ref; |
| 91 | − cursor = &mut storage; | |
| 97 | + cursor = match &mut storage { | |
| 98 | + loose_then_packed::Reference::Loose(r) => r, | |
| 99 | + loose_then_packed::Reference::Packed(_) => unreachable!("handled above - we are done"), | |
| 100 | + }; | |
| 92 | 101 | if seen.contains(&cursor.relative_path) { |
| 93 | 102 | return Err(Error::Cycle(cursor.parent.base.join(&cursor.relative_path))); |
| 94 | 103 | } |