Unified · Split
| @@ -9,7 +9,10 @@ mod method { · 8 unmodified lines | ||
| 9 | 9 | fn target() -> crate::Result { |
| 10 | 10 | let fixture = fixture_bytes("tag", "signed.txt"); |
| 11 | 11 | let tag = Tag::from_bytes(&fixture)?; |
| 12 | − assert_eq!(tag.target(), hex_to_id("ffa700b4aca13b80cb6b98a078e7c96804f8e0ec")); | |
| 12 | + assert_eq!( | |
| 13 | + tag.target.borrow(), | |
| 14 | + hex_to_id("ffa700b4aca13b80cb6b98a078e7c96804f8e0ec") | |
| 15 | + ); | |
| 13 | 16 | assert_eq!(tag.target, "ffa700b4aca13b80cb6b98a078e7c96804f8e0ec".as_bytes()); |
| 14 | 17 | Ok(()) |
| 15 | 18 | } |
| @@ -33,6 +33,7 @@ impl TryFrom<BString> for FullName { · 32 unmodified lines | ||
| 33 | 33 | } |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | +// TODO: remove this one to be consistent with borrowed version | |
| 36 | 37 | impl AsRef<BStr> for FullName { |
| 37 | 38 | fn as_ref(&self) -> &BStr { |
| 38 | 39 | self.0.as_bstr() |
| @@ -59,6 +60,10 @@ impl FullName { · 20 unmodified lines | ||
| 59 | 60 | pub fn into_inner(self) -> BString { |
| 60 | 61 | self.0 |
| 61 | 62 | } |
| 63 | + /// Return ourselves as byte string which is a valid refname | |
| 64 | + pub fn as_bstr(&self) -> &BStr { | |
| 65 | + self.0.as_bstr() | |
| 66 | + } | |
| 62 | 67 | } |
| 63 | 68 | |
| 64 | 69 | /// Denotes a ref target, equivalent to [`Kind`][super::Kind], but with mutable data. |
| @@ -119,11 +119,12 @@ impl file::Store { · 118 unmodified lines | ||
| 119 | 119 | } |
| 120 | 120 | Some(c) => c, |
| 121 | 121 | }; |
| 122 | − Ok(Some( | |
| 123 | − file::Reference::try_from_path(self, &relative_path, &contents) | |
| 122 | + Ok(Some({ | |
| 123 | + let full_name = path_to_name(&relative_path); | |
| 124 | + file::Reference::try_from_path(self, FullName(full_name), &contents) | |
| 124 | 125 | .map(file::loose_then_packed::Reference::Loose) |
| 125 | − .map_err(|err| Error::ReferenceCreation { err, relative_path })?, | |
| 126 | − )) | |
| 126 | + .map_err(|err| Error::ReferenceCreation { err, relative_path })? | |
| 127 | + })) | |
| 127 | 128 | } |
| 128 | 129 | } |
| 129 | 130 | |
| @@ -256,4 +257,5 @@ mod error { · 126 unmodified lines | ||
| 256 | 257 | } |
| 257 | 258 | } |
| 258 | 259 | } |
| 260 | +use crate::mutable::FullName; | |
| 259 | 261 | pub use error::Error; |
| @@ -1,5 +1,5 @@ | ||
| 1 | −use crate::store::file; | |
| 2 | −use bstr::{BString, ByteSlice}; | |
| 1 | +use crate::{mutable::FullName, store::file}; | |
| 2 | +use bstr::ByteSlice; | |
| 3 | 3 | use git_features::fs::walkdir::DirEntryIter; |
| 4 | 4 | use os_str_bytes::OsStrBytes; |
| 5 | 5 | use std::{ |
| @@ -11,31 +11,20 @@ use std::{ · 5 unmodified lines | ||
| 11 | 11 | pub(in crate::store::file) struct SortedLoosePaths { |
| 12 | 12 | base: PathBuf, |
| 13 | 13 | file_walk: DirEntryIter, |
| 14 | − mode: LoosePathsMode, | |
| 15 | −} | |
| 16 | − | |
| 17 | −enum LoosePathsMode { | |
| 18 | − Paths, | |
| 19 | − PathsAndNames, | |
| 20 | 14 | } |
| 21 | 15 | |
| 22 | 16 | impl SortedLoosePaths { |
| 23 | − pub fn at_root(path: impl AsRef<Path>, base: impl Into<PathBuf>) -> Self { | |
| 24 | − Self::new(path.as_ref(), base.into(), LoosePathsMode::Paths) | |
| 25 | − } | |
| 26 | − | |
| 27 | 17 | pub fn at_root_with_names(path: impl AsRef<Path>, base: impl Into<PathBuf>) -> Self { |
| 28 | − Self::new(path.as_ref(), base.into(), LoosePathsMode::PathsAndNames) | |
| 29 | − } | |
| 30 | − | |
| 31 | − fn new(path: &Path, base: PathBuf, mode: LoosePathsMode) -> Self { | |
| 32 | 18 | let file_walk = git_features::fs::walkdir_sorted_new(path).into_iter(); |
| 33 | − SortedLoosePaths { base, file_walk, mode } | |
| 19 | + SortedLoosePaths { | |
| 20 | + base: base.into(), | |
| 21 | + file_walk, | |
| 22 | + } | |
| 34 | 23 | } |
| 35 | 24 | } |
| 36 | 25 | |
| 37 | 26 | impl Iterator for SortedLoosePaths { |
| 38 | − type Item = std::io::Result<(PathBuf, Option<BString>)>; | |
| 27 | + type Item = std::io::Result<(PathBuf, FullName)>; | |
| 39 | 28 | |
| 40 | 29 | fn next(&mut self) -> Option<Self::Item> { |
| 41 | 30 | while let Some(entry) = self.file_walk.next() { |
| @@ -52,15 +41,11 @@ impl Iterator for SortedLoosePaths { · 10 unmodified lines | ||
| 52 | 41 | #[cfg(windows)] |
| 53 | 42 | let full_name: Vec<u8> = full_name.into_owned().replace(b"\\", b"/"); |
| 54 | 43 | |
| 55 | − use LoosePathsMode::*; | |
| 56 | 44 | if git_validate::reference::name_partial(full_name.as_bstr()).is_ok() { |
| 57 | − let name = match self.mode { | |
| 58 | − Paths => None, | |
| 59 | − #[cfg(not(windows))] | |
| 60 | − PathsAndNames => Some(full_name.into_owned().into()), | |
| 61 | − #[cfg(windows)] | |
| 62 | − PathsAndNames => Some(full_name.into()), | |
| 63 | − }; | |
| 45 | + #[cfg(not(windows))] | |
| 46 | + let name = FullName(full_name.into_owned().into()); | |
| 47 | + #[cfg(windows)] | |
| 48 | + let name = FullName(full_name.into()); | |
| 64 | 49 | return Some(Ok((full_path, name))); |
| 65 | 50 | } else { |
| 66 | 51 | continue; |
| @@ -86,7 +71,7 @@ impl<'a> Loose<'a> { · 19 unmodified lines | ||
| 86 | 71 | pub fn at_root(store: &'a file::Store, root: impl AsRef<Path>, base: impl Into<PathBuf>) -> Self { |
| 87 | 72 | Loose { |
| 88 | 73 | parent: store, |
| 89 | − ref_paths: SortedLoosePaths::at_root(root, base), | |
| 74 | + ref_paths: SortedLoosePaths::at_root_with_names(root, base), | |
| 90 | 75 | buf: Vec::new(), |
| 91 | 76 | } |
| 92 | 77 | } |
| @@ -97,26 +82,25 @@ impl<'a> Iterator for Loose<'a> { · 4 unmodified lines | ||
| 97 | 82 | |
| 98 | 83 | fn next(&mut self) -> Option<Self::Item> { |
| 99 | 84 | self.ref_paths.next().map(|res| { |
| 100 | − res.map_err(loose::Error::Traversal) | |
| 101 | − .and_then(|(validated_path, _name)| { | |
| 102 | − std::fs::File::open(&validated_path) | |
| 103 | − .and_then(|mut f| { | |
| 104 | − self.buf.clear(); | |
| 105 | − f.read_to_end(&mut self.buf) | |
| 106 | − }) | |
| 107 | − .map_err(loose::Error::ReadFileContents) | |
| 108 | − .and_then(|_| { | |
| 109 | − let relative_path = validated_path | |
| 110 | − .strip_prefix(&self.ref_paths.base) | |
| 111 | − .expect("root contains path"); | |
| 112 | − file::Reference::try_from_path(self.parent, relative_path, &self.buf).map_err(|err| { | |
| 113 | − loose::Error::ReferenceCreation { | |
| 114 | − err, | |
| 115 | − relative_path: relative_path.into(), | |
| 116 | − } | |
| 117 | − }) | |
| 85 | + res.map_err(loose::Error::Traversal).and_then(|(validated_path, name)| { | |
| 86 | + std::fs::File::open(&validated_path) | |
| 87 | + .and_then(|mut f| { | |
| 88 | + self.buf.clear(); | |
| 89 | + f.read_to_end(&mut self.buf) | |
| 90 | + }) | |
| 91 | + .map_err(loose::Error::ReadFileContents) | |
| 92 | + .and_then(|_| { | |
| 93 | + let relative_path = validated_path | |
| 94 | + .strip_prefix(&self.ref_paths.base) | |
| 95 | + .expect("root contains path"); | |
| 96 | + file::Reference::try_from_path(self.parent, name, &self.buf).map_err(|err| { | |
| 97 | + loose::Error::ReferenceCreation { | |
| 98 | + err, | |
| 99 | + relative_path: relative_path.into(), | |
| 100 | + } | |
| 118 | 101 | }) |
| 119 | − }) | |
| 102 | + }) | |
| 103 | + }) | |
| 120 | 104 | }) |
| 121 | 105 | } |
| 122 | 106 | } |
| @@ -21,9 +21,9 @@ impl Default for WriteReflog { · 20 unmodified lines | ||
| 21 | 21 | pub struct Reference<'a> { |
| 22 | 22 | parent: &'a Store, |
| 23 | 23 | /// The path to uniquely identify this ref within its store. |
| 24 | − // TODO: make this a FullName(BString) and remove the `relative_path()` method entirely. | |
| 25 | − relative_path: PathBuf, | |
| 26 | − target: mutable::Target, | |
| 24 | + pub name: mutable::FullName, | |
| 25 | + /// The target of the reference, either a symbolic reference by full name or an object by its id. | |
| 26 | + pub target: mutable::Target, | |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | 29 | /// A store for reference which uses plain files. |
| @@ -3,7 +3,6 @@ use crate::{ · 2 unmodified lines | ||
| 3 | 3 | file::path_to_name, |
| 4 | 4 | store::{file, packed}, |
| 5 | 5 | }; |
| 6 | −use bstr::BString; | |
| 7 | 6 | use std::{ |
| 8 | 7 | cmp::Ordering, |
| 9 | 8 | io::Read, |
| @@ -27,19 +26,21 @@ impl<'p, 's> LooseThenPacked<'p, 's> { · 17 unmodified lines | ||
| 27 | 26 | }) |
| 28 | 27 | } |
| 29 | 28 | |
| 30 | − fn convert_loose(&mut self, res: std::io::Result<(PathBuf, Option<BString>)>) -> Result<Reference<'p, 's>, Error> { | |
| 31 | − let (refpath, _name) = res.map_err(Error::Traversal)?; | |
| 29 | + fn convert_loose(&mut self, res: std::io::Result<(PathBuf, FullName)>) -> Result<Reference<'p, 's>, Error> { | |
| 30 | + let (refpath, name) = res.map_err(Error::Traversal)?; | |
| 32 | 31 | std::fs::File::open(&refpath) |
| 33 | 32 | .and_then(|mut f| { |
| 34 | 33 | self.buf.clear(); |
| 35 | 34 | f.read_to_end(&mut self.buf) |
| 36 | 35 | }) |
| 37 | 36 | .map_err(Error::ReadFileContents)?; |
| 38 | − let relative_path = refpath.strip_prefix(&self.parent.base).expect("base contains path"); | |
| 39 | − file::Reference::try_from_path(self.parent, relative_path, &self.buf) | |
| 37 | + file::Reference::try_from_path(self.parent, name, &self.buf) | |
| 40 | 38 | .map_err(|err| Error::ReferenceCreation { |
| 41 | 39 | err, |
| 42 | − relative_path: relative_path.into(), | |
| 40 | + relative_path: refpath | |
| 41 | + .strip_prefix(&self.parent.base) | |
| 42 | + .expect("base contains path") | |
| 43 | + .into(), | |
| 43 | 44 | }) |
| 44 | 45 | .map(Reference::Loose) |
| 45 | 46 | } |
| @@ -60,8 +61,8 @@ impl<'p, 's> Iterator for LooseThenPacked<'p, 's> { · 14 unmodified lines | ||
| 60 | 61 | Some(self.convert_loose(res)) |
| 61 | 62 | } |
| 62 | 63 | (Some(Ok(loose)), Some(Ok(packed))) => { |
| 63 | − let loose_name = loose.1.as_ref().expect("name retrieval configured"); | |
| 64 | − match loose_name.as_slice().cmp(packed.full_name) { | |
| 64 | + let loose_name = loose.1.as_ref(); | |
| 65 | + match loose_name.cmp(packed.full_name) { | |
| 65 | 66 | Ordering::Less => { |
| 66 | 67 | let res = self.loose.next().expect("name retrieval configured"); |
| 67 | 68 | Some(self.convert_loose(res)) |
| @@ -154,4 +155,5 @@ mod error { · 86 unmodified lines | ||
| 154 | 155 | } |
| 155 | 156 | } |
| 156 | 157 | |
| 158 | +use crate::mutable::FullName; | |
| 157 | 159 | pub use error::Error; |
| @@ -1,16 +1,14 @@ | ||
| 1 | 1 | use super::Reference; |
| 2 | 2 | use crate::{ |
| 3 | − mutable, | |
| 3 | + mutable, name, | |
| 4 | 4 | store::{ |
| 5 | 5 | file::{log, loose}, |
| 6 | 6 | packed, |
| 7 | 7 | }, |
| 8 | + FullName, | |
| 8 | 9 | }; |
| 9 | 10 | use git_hash::oid; |
| 10 | −use std::{ | |
| 11 | − convert::{TryFrom, TryInto}, | |
| 12 | − path::Path, | |
| 13 | −}; | |
| 11 | +use std::convert::{TryFrom, TryInto}; | |
| 14 | 12 | |
| 15 | 13 | impl<'p, 's> TryFrom<Reference<'p, 's>> for crate::file::Reference<'s> { |
| 16 | 14 | type Error = (); |
| @@ -32,14 +30,6 @@ impl<'p, 's> Reference<'p, 's> { · 15 unmodified lines | ||
| 32 | 30 | } |
| 33 | 31 | } |
| 34 | 32 | |
| 35 | − /// Return the full name of this reference as path, only applicable if this is a loose reference. | |
| 36 | − pub fn relative_path(&self) -> Option<&Path> { | |
| 37 | − match self { | |
| 38 | − Reference::Loose(r) => Some(r.relative_path()), | |
| 39 | − Reference::Packed(_) => None, | |
| 40 | − } | |
| 41 | − } | |
| 42 | − | |
| 43 | 33 | /// For details, see [crate::file::Reference::peel_to_id_in_place]. |
| 44 | 34 | pub fn peel_to_id_in_place( |
| 45 | 35 | &mut self, |
| @@ -96,7 +86,7 @@ impl<'p, 's> Reference<'p, 's> { · 50 unmodified lines | ||
| 96 | 86 | pub fn into_target(self) -> mutable::Target { |
| 97 | 87 | match self { |
| 98 | 88 | Reference::Packed(p) => mutable::Target::Peeled(p.object()), |
| 99 | − Reference::Loose(r) => r.into_target(), | |
| 89 | + Reference::Loose(r) => r.target, | |
| 100 | 90 | } |
| 101 | 91 | } |
| 102 | 92 | |
| @@ -109,10 +99,10 @@ impl<'p, 's> Reference<'p, 's> { · 6 unmodified lines | ||
| 109 | 99 | } |
| 110 | 100 | |
| 111 | 101 | /// Return the full validated name of the reference. Please note that if the reference is packed, validation can fail here. |
| 112 | − pub fn name(&self) -> Result<mutable::FullName, git_validate::refname::Error> { | |
| 102 | + pub fn name(&self) -> Result<FullName<'_>, name::Error> { | |
| 113 | 103 | match self { |
| 114 | 104 | Reference::Packed(p) => p.full_name.try_into(), |
| 115 | − Reference::Loose(l) => Ok(l.name()), | |
| 105 | + Reference::Loose(l) => Ok(l.name.borrow()), | |
| 116 | 106 | } |
| 117 | 107 | } |
| 118 | 108 | |
| @@ -120,7 +110,7 @@ impl<'p, 's> Reference<'p, 's> { · 1 unmodified line | ||
| 120 | 110 | pub fn target(&self) -> mutable::Target { |
| 121 | 111 | match self { |
| 122 | 112 | Reference::Packed(p) => mutable::Target::Peeled(p.target()), |
| 123 | − Reference::Loose(l) => l.target().to_owned(), | |
| 113 | + Reference::Loose(l) => l.target.clone(), | |
| 124 | 114 | } |
| 125 | 115 | } |
| 126 | 116 | } |
| @@ -12,10 +12,7 @@ use nom::{ · 11 unmodified lines | ||
| 12 | 12 | IResult, |
| 13 | 13 | }; |
| 14 | 14 | use quick_error::quick_error; |
| 15 | −use std::{ | |
| 16 | − convert::{TryFrom, TryInto}, | |
| 17 | − path::PathBuf, | |
| 18 | −}; | |
| 15 | +use std::convert::{TryFrom, TryInto}; | |
| 19 | 16 | |
| 20 | 17 | enum MaybeUnsafeState { |
| 21 | 18 | Id(ObjectId), |
| @@ -56,14 +53,10 @@ impl TryFrom<MaybeUnsafeState> for mutable::Target { · 34 unmodified lines | ||
| 56 | 53 | impl<'a> Reference<'a> { |
| 57 | 54 | /// Create a new reference of the given `parent` store with `relative_path` service as unique identifier |
| 58 | 55 | /// at which the `path_contents` was read to obtain the refs value. |
| 59 | − pub fn try_from_path( | |
| 60 | − parent: &'a Store, | |
| 61 | − relative_path: impl Into<PathBuf>, | |
| 62 | − path_contents: &[u8], | |
| 63 | − ) -> Result<Self, Error> { | |
| 56 | + pub fn try_from_path(parent: &'a Store, name: mutable::FullName, path_contents: &[u8]) -> Result<Self, Error> { | |
| 64 | 57 | Ok(Reference { |
| 65 | 58 | parent, |
| 66 | − relative_path: relative_path.into(), | |
| 59 | + name, | |
| 67 | 60 | target: parse(path_contents) |
| 68 | 61 | .map_err(|_| Error::Parse(path_contents.into()))? |
| 69 | 62 | .1 |
| @@ -1,8 +1,4 @@ | ||
| 1 | −use crate::{ | |
| 2 | − store::file::{log, loose, Reference}, | |
| 3 | − FullName, | |
| 4 | −}; | |
| 5 | −use bstr::ByteSlice; | |
| 1 | +use crate::store::file::{log, loose, Reference}; | |
| 6 | 2 | use std::io::Read; |
| 7 | 3 | |
| 8 | 4 | impl<'a> Reference<'a> { |
| @@ -13,9 +9,7 @@ impl<'a> Reference<'a> { · 4 unmodified lines | ||
| 13 | 9 | /// If the caller needs to know if it's readable, try to read the log instead with a reverse or forward iterator. |
| 14 | 10 | pub fn log_exists(&self) -> Result<bool, loose::reflog::Error> { |
| 15 | 11 | // NOTE: Have to repeat the implementation of store::reflog_iter here as borrow_check believes impl Iterator binds self |
| 16 | − use os_str_bytes::OsStrBytes; | |
| 17 | − let name = self.relative_path.as_path().to_raw_bytes(); | |
| 18 | − Ok(self.parent.reflog_path(FullName(name.as_bstr())).is_file()) | |
| 12 | + Ok(self.parent.reflog_path(self.name.borrow()).is_file()) | |
| 19 | 13 | } |
| 20 | 14 | /// Return a reflog reverse iterator for this ref, reading chunks from the back into the fixed buffer `buf`. |
| 21 | 15 | /// |
| @@ -26,9 +20,7 @@ impl<'a> Reference<'a> { · 4 unmodified lines | ||
| 26 | 20 | buf: &'b mut [u8], |
| 27 | 21 | ) -> Result<Option<log::iter::Reverse<'b, std::fs::File>>, loose::reflog::Error> { |
| 28 | 22 | // NOTE: Have to repeat the implementation of store::reflog_iter here as borrow_check believes impl Iterator binds self |
| 29 | − use os_str_bytes::OsStrBytes; | |
| 30 | − let name = self.relative_path.as_path().to_raw_bytes(); | |
| 31 | − let file = match std::fs::File::open(self.parent.reflog_path(FullName(name.as_bstr()))) { | |
| 23 | + let file = match std::fs::File::open(self.parent.reflog_path(self.name.borrow())) { | |
| 32 | 24 | Ok(file) => file, |
| 33 | 25 | Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None), |
| 34 | 26 | Err(err) => return Err(err.into()), |
| @@ -46,9 +38,7 @@ impl<'a> Reference<'a> { · 11 unmodified lines | ||
| 46 | 38 | ) -> Result<Option<impl Iterator<Item = Result<log::Line<'b>, log::iter::decode::Error>>>, loose::reflog::Error> |
| 47 | 39 | { |
| 48 | 40 | // NOTE: Have to repeat the implementation of store::reflog_iter here as borrow_check believes impl Iterator binds self |
| 49 | − use os_str_bytes::OsStrBytes; | |
| 50 | − let name = self.relative_path.as_path().to_raw_bytes(); | |
| 51 | − match std::fs::File::open(self.parent.reflog_path(FullName(name.as_bstr()))) { | |
| 41 | + match std::fs::File::open(self.parent.reflog_path(self.name.borrow())) { | |
| 52 | 42 | Ok(mut file) => { |
| 53 | 43 | buf.clear(); |
| 54 | 44 | file.read_to_end(buf)?; |
| @@ -1,45 +1,10 @@ | ||
| 1 | −use crate::{file::Reference, mutable, mutable::FullName, Kind, Target}; | |
| 2 | −use std::path::{Path, PathBuf}; | |
| 1 | +use crate::{file::Reference, Kind}; | |
| 3 | 2 | |
| 4 | 3 | impl<'a> Reference<'a> { |
| 5 | 4 | /// Return the kind of ref. |
| 6 | 5 | pub fn kind(&self) -> Kind { |
| 7 | 6 | self.target.kind() |
| 8 | 7 | } |
| 9 | − | |
| 10 | − /// Return the target to which this instance is pointing. | |
| 11 | − pub fn target(&self) -> Target<'_> { | |
| 12 | − self.target.borrow() | |
| 13 | − } | |
| 14 | − | |
| 15 | − /// Transform this reference into an owned `Target` | |
| 16 | − pub fn into_target(self) -> mutable::Target { | |
| 17 | − self.target | |
| 18 | − } | |
| 19 | − | |
| 20 | − /// Return the full name of this reference as path. | |
| 21 | − /// | |
| 22 | − /// Use [`name()`][Reference::name()] if consistent component separators are required across platforms. | |
| 23 | − pub fn relative_path(&self) -> &Path { | |
| 24 | − &self.relative_path | |
| 25 | − } | |
| 26 | − | |
| 27 | − /// Return our relative path while consuming this instance | |
| 28 | − pub fn into_relative_path(self) -> PathBuf { | |
| 29 | − self.relative_path | |
| 30 | − } | |
| 31 | − | |
| 32 | − /// Return the full validated name of the reference | |
| 33 | − pub fn name(&self) -> FullName { | |
| 34 | − use os_str_bytes::OsStrBytes; | |
| 35 | − let name = self.relative_path.as_path().to_raw_bytes(); | |
| 36 | − #[cfg(windows)] | |
| 37 | − let name = { | |
| 38 | − use bstr::ByteSlice; | |
| 39 | − name.replace(b"\\", b"/") | |
| 40 | − }; | |
| 41 | − FullName(name.to_vec().into()) | |
| 42 | − } | |
| 43 | 8 | } |
| 44 | 9 | |
| 45 | 10 | mod logiter; |
| @@ -98,10 +98,10 @@ pub mod to_id { · 97 unmodified lines | ||
| 98 | 98 | loose_then_packed::Reference::Loose(r) => r, |
| 99 | 99 | loose_then_packed::Reference::Packed(_) => unreachable!("handled above - we are done"), |
| 100 | 100 | }; |
| 101 | − if seen.contains(&cursor.relative_path) { | |
| 102 | − return Err(Error::Cycle(cursor.parent.base.join(&cursor.relative_path))); | |
| 101 | + if seen.contains(&cursor.name) { | |
| 102 | + return Err(Error::Cycle(cursor.parent.base.join(cursor.name.to_path()))); | |
| 103 | 103 | } |
| 104 | − seen.insert(cursor.relative_path.clone()); | |
| 104 | + seen.insert(cursor.name.clone()); | |
| 105 | 105 | count += 1; |
| 106 | 106 | const MAX_REF_DEPTH: usize = 5; |
| 107 | 107 | if count == MAX_REF_DEPTH { |
| @@ -60,8 +60,10 @@ impl<'a> Transaction<'a> { · 59 unmodified lines | ||
| 60 | 60 | .ref_contents(relative_path.as_ref()) |
| 61 | 61 | .map_err(Error::from) |
| 62 | 62 | .and_then(|opt| { |
| 63 | − opt.map(|buf| file::Reference::try_from_path(store, relative_path.as_ref(), &buf).map_err(Error::from)) | |
| 64 | − .transpose() | |
| 63 | + opt.map(|buf| { | |
| 64 | + file::Reference::try_from_path(store, change.update.name.clone(), &buf).map_err(Error::from) | |
| 65 | + }) | |
| 66 | + .transpose() | |
| 65 | 67 | }) |
| 66 | 68 | .or_else(|err| match err { |
| 67 | 69 | Error::ReferenceDecode(_) => Ok(None), |
| @@ -87,12 +89,12 @@ impl<'a> Transaction<'a> { · 19 unmodified lines | ||
| 87 | 89 | }) |
| 88 | 90 | } |
| 89 | 91 | (Some(previous), Some(existing)) => { |
| 90 | − if !previous.is_null() && *previous != existing.target() { | |
| 92 | + if !previous.is_null() && *previous != existing.target { | |
| 91 | 93 | let expected = previous.clone(); |
| 92 | 94 | return Err(Error::ReferenceOutOfDate { |
| 93 | 95 | full_name: change.name(), |
| 94 | 96 | expected, |
| 95 | − actual: existing.target().to_owned(), | |
| 97 | + actual: existing.target.to_owned(), | |
| 96 | 98 | }); |
| 97 | 99 | } |
| 98 | 100 | } |
| @@ -100,7 +102,7 @@ impl<'a> Transaction<'a> { · 1 unmodified line | ||
| 100 | 102 | |
| 101 | 103 | // Keep the previous value for the caller and ourselves. Maybe they want to keep a log of sorts. |
| 102 | 104 | if let Some(existing) = existing_ref { |
| 103 | − *previous = Some(existing.target().into()); | |
| 105 | + *previous = Some(existing.target.into()); | |
| 104 | 106 | } |
| 105 | 107 | |
| 106 | 108 | lock |
| @@ -120,11 +122,11 @@ impl<'a> Transaction<'a> { · 13 unmodified lines | ||
| 120 | 122 | |
| 121 | 123 | let existing_ref = existing_ref?; |
| 122 | 124 | match (&previous, &existing_ref) { |
| 123 | − (Create::Only, Some(existing)) if existing.target() != new.borrow() => { | |
| 125 | + (Create::Only, Some(existing)) if existing.target != new.borrow() => { | |
| 124 | 126 | let new = new.clone(); |
| 125 | 127 | return Err(Error::MustNotExist { |
| 126 | 128 | full_name: change.name(), |
| 127 | − actual: existing.target().to_owned(), | |
| 129 | + actual: existing.target.to_owned(), | |
| 128 | 130 | new, |
| 129 | 131 | }); |
| 130 | 132 | } |
| @@ -135,9 +137,9 @@ impl<'a> Transaction<'a> { · 4 unmodified lines | ||
| 135 | 137 | Some(existing), |
| 136 | 138 | ) => match previous { |
| 137 | 139 | Target::Peeled(oid) if oid.is_null() => {} |
| 138 | − any_target if any_target.borrow() == existing.target() => {} | |
| 140 | + any_target if *any_target == existing.target => {} | |
| 139 | 141 | _target_mismatch => { |
| 140 | − let actual = existing.target().to_owned(); | |
| 142 | + let actual = existing.target.to_owned(); | |
| 141 | 143 | let expected = previous.to_owned(); |
| 142 | 144 | let full_name = change.name(); |
| 143 | 145 | return Err(Error::ReferenceOutOfDate { |
| @@ -163,7 +165,7 @@ impl<'a> Transaction<'a> { · 19 unmodified lines | ||
| 163 | 165 | *previous = match existing_ref { |
| 164 | 166 | None => Create::Only, |
| 165 | 167 | Some(existing) => Create::OrUpdate { |
| 166 | − previous: Some(existing.target().into()), | |
| 168 | + previous: Some(existing.target.into()), | |
| 167 | 169 | }, |
| 168 | 170 | }; |
| 169 | 171 | |
| @@ -4,7 +4,7 @@ mod reflog { · 3 unmodified lines | ||
| 4 | 4 | #[test] |
| 5 | 5 | fn iter() -> crate::Result { |
| 6 | 6 | let store = file::store()?; |
| 7 | − let r = store.find_existing("HEAD", None)?; | |
| 7 | + let r = store.loose_find_existing("HEAD")?; | |
| 8 | 8 | let mut buf = Vec::new(); |
| 9 | 9 | assert_eq!(r.log_iter(&mut buf)?.expect("log exists").count(), 1); |
| 10 | 10 | Ok(()) |
| @@ -13,7 +13,7 @@ mod reflog { · 2 unmodified lines | ||
| 13 | 13 | #[test] |
| 14 | 14 | fn iter_rev() -> crate::Result { |
| 15 | 15 | let store = file::store()?; |
| 16 | − let r = store.find_existing("HEAD", None)?; | |
| 16 | + let r = store.loose_find_existing("HEAD")?; | |
| 17 | 17 | let mut buf = [0u8; 256]; |
| 18 | 18 | assert_eq!(r.log_iter_rev(&mut buf)?.expect("log exists").count(), 1); |
| 19 | 19 | Ok(()) |
| @@ -21,11 +21,9 @@ mod reflog { · 1 unmodified line | ||
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | mod peel { |
| 24 | − use crate::file; | |
| 25 | − use crate::file::store_with_packed_refs; | |
| 24 | + use crate::{file, file::store_with_packed_refs}; | |
| 26 | 25 | use git_testtools::hex_to_id; |
| 27 | 26 | use std::convert::TryFrom; |
| 28 | − use std::path::Path; | |
| 29 | 27 | |
| 30 | 28 | #[test] |
| 31 | 29 | fn one_level() -> crate::Result { |
| @@ -36,12 +34,12 @@ mod peel { · 4 unmodified lines | ||
| 36 | 34 | let nr = git_ref::file::Reference::try_from(r.peel_one_level(None).expect("exists").expect("no failure")) |
| 37 | 35 | .expect("loose ref"); |
| 38 | 36 | assert!( |
| 39 | − matches!(nr.target(), git_ref::Target::Peeled(_)), | |
| 37 | + matches!(nr.target.borrow(), git_ref::Target::Peeled(_)), | |
| 40 | 38 | "iteration peels a single level" |
| 41 | 39 | ); |
| 42 | 40 | assert!(nr.peel_one_level(None).is_none(), "end of iteration"); |
| 43 | 41 | assert_eq!( |
| 44 | − nr.target(), | |
| 42 | + nr.target.borrow(), | |
| 45 | 43 | git_ref::Target::Peeled(&hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03")), |
| 46 | 44 | "we still have the peeled target" |
| 47 | 45 | ); |
| @@ -69,7 +67,7 @@ mod peel { · 21 unmodified lines | ||
| 69 | 67 | r.peel_to_id_in_place(None)?, |
| 70 | 68 | hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03") |
| 71 | 69 | ); |
| 72 | − assert_eq!(r.relative_path(), Path::new("refs/remotes/origin/multi-link-target3")); | |
| 70 | + assert_eq!(r.name.as_ref(), "refs/remotes/origin/multi-link-target3"); | |
| 73 | 71 | |
| 74 | 72 | Ok(()) |
| 75 | 73 | } |
| @@ -79,17 +77,13 @@ mod peel { · 3 unmodified lines | ||
| 79 | 77 | let store = file::store()?; |
| 80 | 78 | let mut r = store.loose_find_existing("loop-a")?; |
| 81 | 79 | assert_eq!(r.kind(), git_ref::Kind::Symbolic, "there is something to peel"); |
| 82 | − assert_eq!(r.relative_path(), Path::new("refs/loop-a")); | |
| 80 | + assert_eq!(r.name.as_ref(), "refs/loop-a"); | |
| 83 | 81 | |
| 84 | 82 | assert!(matches!( |
| 85 | 83 | r.peel_to_id_in_place(None).unwrap_err(), |
| 86 | 84 | git_ref::file::reference::peel::to_id::Error::Cycle { .. } |
| 87 | 85 | )); |
| 88 | − assert_eq!( | |
| 89 | − r.relative_path(), | |
| 90 | − Path::new("refs/loop-a"), | |
| 91 | − "the ref is not changed on error" | |
| 92 | − ); | |
| 86 | + assert_eq!(r.name.as_ref(), "refs/loop-a", "the ref is not changed on error"); | |
| 93 | 87 | Ok(()) |
| 94 | 88 | } |
| 95 | 89 | } |
| @@ -109,8 +103,14 @@ mod parse { · 13 unmodified lines | ||
| 109 | 103 | ($name:ident, $input:literal, $err:literal) => { |
| 110 | 104 | #[test] |
| 111 | 105 | fn $name() { |
| 106 | + use std::convert::TryInto; | |
| 112 | 107 | let store = store(); |
| 113 | − let err = Reference::try_from_path(&store, "name", $input).unwrap_err(); | |
| 108 | + let err = Reference::try_from_path( | |
| 109 | + &store, | |
| 110 | + "HEAD".try_into().expect("this is a valid name"), | |
| 111 | + $input, | |
| 112 | + ) | |
| 113 | + .unwrap_err(); | |
| 114 | 114 | assert_eq!(err.to_string(), $err); |
| 115 | 115 | } |
| 116 | 116 | }; |
| @@ -129,11 +129,17 @@ mod parse { · 12 unmodified lines | ||
| 129 | 129 | ($name:ident, $input:literal, $kind:path, $id:expr, $ref:expr) => { |
| 130 | 130 | #[test] |
| 131 | 131 | fn $name() { |
| 132 | + use std::convert::TryInto; | |
| 132 | 133 | let store = store(); |
| 133 | − let reference = Reference::try_from_path(&store, "name", $input).unwrap(); | |
| 134 | + let reference = Reference::try_from_path( | |
| 135 | + &store, | |
| 136 | + "HEAD".try_into().expect("valid static name"), | |
| 137 | + $input, | |
| 138 | + ) | |
| 139 | + .unwrap(); | |
| 134 | 140 | assert_eq!(reference.kind(), $kind); |
| 135 | − assert_eq!(reference.target().as_id(), $id); | |
| 136 | − assert_eq!(reference.target().as_name(), $ref); | |
| 141 | + assert_eq!(reference.target.borrow().as_id(), $id); | |
| 142 | + assert_eq!(reference.target.borrow().as_name(), $ref); | |
| 137 | 143 | } |
| 138 | 144 | }; |
| 139 | 145 | } |
| @@ -1,6 +1,5 @@ | ||
| 1 | 1 | use crate::file::{store, store_at}; |
| 2 | 2 | use git_testtools::hex_to_id; |
| 3 | −use std::path::Path; | |
| 4 | 3 | |
| 5 | 4 | mod existing { |
| 6 | 5 | use crate::file::store; |
| @@ -12,7 +11,7 @@ mod existing { · 5 unmodified lines | ||
| 12 | 11 | for (partial_name, expected_path) in &[("main", Some("refs/heads/main")), ("does-not-exist", None)] { |
| 13 | 12 | let reference = store.loose_find_existing(*partial_name); |
| 14 | 13 | match expected_path { |
| 15 | − Some(expected_path) => assert_eq!(reference?.relative_path(), Path::new(expected_path)), | |
| 14 | + Some(expected_path) => assert_eq!(reference?.name.as_ref(), expected_path), | |
| 16 | 15 | None => match reference { |
| 17 | 16 | Ok(_) => panic!("Expected error"), |
| 18 | 17 | Err(git_ref::file::find::existing::Error::NotFound(name)) => { |
| @@ -33,7 +32,7 @@ fn with_packed_refs() -> crate::Result { · 14 unmodified lines | ||
| 33 | 32 | let packed = store.packed()?; |
| 34 | 33 | let r = store.find_existing("main", packed.as_ref())?; |
| 35 | 34 | assert_eq!(r.target().borrow().as_id().expect("peeled"), c1); |
| 36 | − assert_eq!(r.name().expect("valid name").as_ref(), "refs/heads/main"); | |
| 35 | + assert_eq!(r.name().expect("valid name").as_bstr(), "refs/heads/main"); | |
| 37 | 36 | Ok(()) |
| 38 | 37 | } |
| 39 | 38 | |
| @@ -55,8 +54,8 @@ fn success() -> crate::Result { · 15 unmodified lines | ||
| 55 | 54 | ("refs/heads/main", "refs/heads/main", git_ref::Kind::Peeled), |
| 56 | 55 | ] { |
| 57 | 56 | let reference = store.loose_find(*partial_name)?.expect("exists"); |
| 58 | − assert_eq!(reference.relative_path(), Path::new(expected_path)); | |
| 59 | − assert_eq!(reference.target().kind(), *expected_ref_kind); | |
| 57 | + assert_eq!(reference.name.as_bstr(), expected_path); | |
| 58 | + assert_eq!(reference.target.borrow().kind(), *expected_ref_kind); | |
| 60 | 59 | } |
| 61 | 60 | Ok(()) |
| 62 | 61 | } |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | use crate::file::{store, store_at, store_with_packed_refs}; |
| 2 | 2 | use bstr::ByteSlice; |
| 3 | 3 | use git_testtools::hex_to_id; |
| 4 | −use std::{convert::TryInto, path::PathBuf}; | |
| 4 | +use std::convert::TryInto; | |
| 5 | 5 | |
| 6 | 6 | #[test] |
| 7 | 7 | fn no_packed_available_thus_no_iteration_possible() -> crate::Result { |
| @@ -47,7 +47,7 @@ fn loose_iter_with_broken_refs() -> crate::Result { · 39 unmodified lines | ||
| 47 | 47 | ); |
| 48 | 48 | let ref_paths: Vec<_> = actual |
| 49 | 49 | .drain(..first_error) |
| 50 | − .filter_map(|e| e.ok().map(|e| e.into_relative_path())) | |
| 50 | + .filter_map(|e| e.ok().map(|e| e.name.into_inner())) | |
| 51 | 51 | .collect(); |
| 52 | 52 | |
| 53 | 53 | assert_eq!( |
| @@ -69,7 +69,7 @@ fn loose_iter_with_broken_refs() -> crate::Result { · 15 unmodified lines | ||
| 69 | 69 | "tags/t1" |
| 70 | 70 | ] |
| 71 | 71 | .into_iter() |
| 72 | − .map(|p| PathBuf::from(format!("refs/{}", p))) | |
| 72 | + .map(|p| format!("refs/{}", p)) | |
| 73 | 73 | .collect::<Vec<_>>(), |
| 74 | 74 | "all paths are as expected" |
| 75 | 75 | ); |
| @@ -100,7 +100,7 @@ fn loose_iter_with_prefix() -> crate::Result { · 24 unmodified lines | ||
| 100 | 100 | .collect::<Result<Vec<_>, _>>() |
| 101 | 101 | .expect("no broken ref in this subset") |
| 102 | 102 | .into_iter() |
| 103 | − .map(|e| e.into_relative_path()) | |
| 103 | + .map(|e| e.name.into_inner()) | |
| 104 | 104 | .collect::<Vec<_>>(); |
| 105 | 105 | |
| 106 | 106 | assert_eq!( |
| @@ -112,7 +112,7 @@ fn loose_iter_with_prefix() -> crate::Result { · 5 unmodified lines | ||
| 112 | 112 | "refs/heads/multi-link-target1", |
| 113 | 113 | ] |
| 114 | 114 | .into_iter() |
| 115 | − .map(PathBuf::from) | |
| 115 | + .map(String::from) | |
| 116 | 116 | .collect::<Vec<_>>(), |
| 117 | 117 | "all paths are as expected" |
| 118 | 118 | ); |
| @@ -129,7 +129,7 @@ fn overlay_iter() -> crate::Result { · 10 unmodified lines | ||
| 129 | 129 | .map(|r| { |
| 130 | 130 | r.map(|r| { |
| 131 | 131 | ( |
| 132 | − r.name().expect("valid names only").into_inner(), | |
| 132 | + r.name().expect("valid names only").as_bstr().to_owned(), | |
| 133 | 133 | r.target(), |
| 134 | 134 | r.is_packed(), |
| 135 | 135 | ) |
| @@ -185,7 +185,7 @@ fn overlay_prefixed_iter() -> crate::Result { · 49 unmodified lines | ||
| 185 | 185 | .map(|r| { |
| 186 | 186 | r.map(|r| { |
| 187 | 187 | ( |
| 188 | − r.name().expect("valid names only").into_inner(), | |
| 188 | + r.name().expect("valid names only").as_bstr().to_owned(), | |
| 189 | 189 | r.target(), |
| 190 | 190 | r.is_packed(), |
| 191 | 191 | ) |
| @@ -11,7 +11,7 @@ use git_ref::{ · 10 unmodified lines | ||
| 11 | 11 | transaction::{Change, Create, LogChange, RefEdit, RefLog}, |
| 12 | 12 | }; |
| 13 | 13 | use git_testtools::hex_to_id; |
| 14 | −use std::{convert::TryInto, path::Path}; | |
| 14 | +use std::convert::TryInto; | |
| 15 | 15 | |
| 16 | 16 | mod reference_with_equally_named { |
| 17 | 17 | use crate::file::transaction::prepare_and_commit::{committer, empty_store}; |
| @@ -50,7 +50,7 @@ mod reference_with_equally_named { · 32 unmodified lines | ||
| 50 | 50 | if *is_empty { |
| 51 | 51 | let edits = edits?; |
| 52 | 52 | assert!( |
| 53 | − store.find(edits[0].name.to_partial(), None)?.is_some(), | |
| 53 | + store.loose_find(edits[0].name.to_partial())?.is_some(), | |
| 54 | 54 | "HEAD was created despite a directory being in the way" |
| 55 | 55 | ); |
| 56 | 56 | } else { |
| @@ -108,8 +108,8 @@ fn reference_with_old_value_must_exist_when_creating_it() -> crate::Result { · 51 unmodified lines | ||
| 108 | 108 | #[test] |
| 109 | 109 | fn reference_with_explicit_value_must_match_the_value_on_update() -> crate::Result { |
| 110 | 110 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 111 | − let head = store.find("HEAD", None)?.expect("head exists already"); | |
| 112 | − let target = head.target().to_owned(); | |
| 111 | + let head = store.loose_find("HEAD")?.expect("head exists already"); | |
| 112 | + let target = head.target; | |
| 113 | 113 | |
| 114 | 114 | let err = store |
| 115 | 115 | .transaction( |
| @@ -144,8 +144,8 @@ fn reference_with_explicit_value_must_match_the_value_on_update() -> crate::Resu · 28 unmodified lines | ||
| 144 | 144 | #[test] |
| 145 | 145 | fn reference_with_create_only_must_not_exist_already_when_creating_it_if_the_value_does_not_match() -> crate::Result { |
| 146 | 146 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 147 | − let head = store.find("HEAD", None)?.expect("head exists already"); | |
| 148 | − let target = head.target().to_owned(); | |
| 147 | + let head = store.loose_find("HEAD")?.expect("head exists already"); | |
| 148 | + let target = head.target; | |
| 149 | 149 | |
| 150 | 150 | let err = store |
| 151 | 151 | .transaction( |
| @@ -178,8 +178,8 @@ fn reference_with_create_only_must_not_exist_already_when_creating_it_if_the_val · 26 unmodified lines | ||
| 178 | 178 | #[test] |
| 179 | 179 | fn reference_with_create_only_must_not_exist_already_when_creating_it_unless_the_value_matches() -> crate::Result { |
| 180 | 180 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 181 | − let head = store.find("HEAD", None)?.expect("head exists already"); | |
| 182 | − let target = head.target().to_owned(); | |
| 181 | + let head = store.loose_find("HEAD")?.expect("head exists already"); | |
| 182 | + let target = head.target; | |
| 183 | 183 | let previous_reflog_count = reflog_lines(&store, "HEAD")?.len(); |
| 184 | 184 | |
| 185 | 185 | let edits = store |
| @@ -258,7 +258,7 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { · 72 unmodified lines | ||
| 258 | 258 | let (_keep, mut store) = empty_store()?; |
| 259 | 259 | store.write_reflog = *reflog_writemode; |
| 260 | 260 | let referent = "refs/heads/alt-main"; |
| 261 | − assert!(store.find(referent, None)?.is_none(), "the reference does not exist"); | |
| 261 | + assert!(store.loose_find(referent)?.is_none(), "the reference does not exist"); | |
| 262 | 262 | let log_ignored = LogChange { |
| 263 | 263 | mode: RefLog::AndReference, |
| 264 | 264 | force_create_reflog: false, |
| @@ -294,11 +294,11 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { · 29 unmodified lines | ||
| 294 | 294 | ); |
| 295 | 295 | |
| 296 | 296 | let head = store.loose_find_existing(edits[0].name.to_partial())?; |
| 297 | − assert_eq!(head.relative_path(), Path::new("HEAD")); | |
| 297 | + assert_eq!(head.name.as_bstr(), "HEAD"); | |
| 298 | 298 | assert_eq!(head.kind(), git_ref::Kind::Symbolic); |
| 299 | − assert_eq!(head.target().as_name(), Some(referent.as_bytes().as_bstr())); | |
| 299 | + assert_eq!(head.target.borrow().as_name(), Some(referent.as_bytes().as_bstr())); | |
| 300 | 300 | assert!(!head.log_exists()?, "no reflog is written for symbolic ref"); |
| 301 | − assert!(store.find(referent, None)?.is_none(), "referent wasn't created"); | |
| 301 | + assert!(store.loose_find(referent)?.is_none(), "referent wasn't created"); | |
| 302 | 302 | |
| 303 | 303 | let new_oid = hex_to_id("28ce6a8b26aa170e1de65536fe8abe1832bd3242"); |
| 304 | 304 | let new = Target::Peeled(new_oid); |
| @@ -360,7 +360,7 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { · 55 unmodified lines | ||
| 360 | 360 | "head is still symbolic, not detached" |
| 361 | 361 | ); |
| 362 | 362 | assert_eq!( |
| 363 | − head.target().as_name(), | |
| 363 | + head.target.borrow().as_name(), | |
| 364 | 364 | Some(referent.as_bytes().as_bstr()), |
| 365 | 365 | "it still points to the referent" |
| 366 | 366 | ); |
| @@ -368,7 +368,7 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { · 1 unmodified line | ||
| 368 | 368 | let referent_ref = store.loose_find_existing(referent)?; |
| 369 | 369 | assert_eq!(referent_ref.kind(), git_ref::Kind::Peeled, "referent is a peeled ref"); |
| 370 | 370 | assert_eq!( |
| 371 | − referent_ref.target().as_id(), | |
| 371 | + referent_ref.target.borrow().as_id(), | |
| 372 | 372 | Some(new_oid.as_ref()), |
| 373 | 373 | "referent points to desired hash" |
| 374 | 374 | ); |
| @@ -398,7 +398,7 @@ fn symbolic_head_missing_referent_then_update_referent() -> crate::Result { · 23 unmodified lines | ||
| 398 | 398 | fn write_reference_to_which_head_points_to_does_not_update_heads_reflog_even_though_it_should() -> crate::Result { |
| 399 | 399 | let (_keep, store) = store_writable("make_repo_for_reflog.sh")?; |
| 400 | 400 | let head = store.loose_find_existing("HEAD")?; |
| 401 | − let referent = head.target().as_name().expect("symbolic ref").to_owned(); | |
| 401 | + let referent = head.target.borrow().as_name().expect("symbolic ref").to_owned(); | |
| 402 | 402 | let previous_head_reflog = reflog_lines(&store, "HEAD")?; |
| 403 | 403 | |
| 404 | 404 | let new_id = hex_to_id("01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc"); |
| @@ -67,7 +67,7 @@ fn delete_ref_and_reflog_on_symbolic_no_deref() -> crate::Result { · 66 unmodified lines | ||
| 67 | 67 | previous: Some(Target::must_exist()), |
| 68 | 68 | log: RefLog::AndReference, |
| 69 | 69 | }, |
| 70 | − name: head.name().into(), | |
| 70 | + name: head.name.clone(), | |
| 71 | 71 | deref: false, |
| 72 | 72 | }), |
| 73 | 73 | Fail::Immediately, |
| @@ -81,7 +81,7 @@ fn delete_ref_and_reflog_on_symbolic_no_deref() -> crate::Result { · 7 unmodified lines | ||
| 81 | 81 | previous: Some(Target::Symbolic("refs/heads/main".try_into()?)), |
| 82 | 82 | log: RefLog::AndReference, |
| 83 | 83 | }, |
| 84 | − name: head.name().into(), | |
| 84 | + name: head.name, | |
| 85 | 85 | deref: false |
| 86 | 86 | }], |
| 87 | 87 | "the previous value was updated with the actual one" |
| @@ -90,8 +90,8 @@ fn delete_ref_and_reflog_on_symbolic_no_deref() -> crate::Result { · 2 unmodified lines | ||
| 90 | 90 | store.reflog_iter_rev("HEAD", &mut [0u8; 128])?.is_none(), |
| 91 | 91 | "reflog was deleted" |
| 92 | 92 | ); |
| 93 | − assert!(store.find("HEAD", None)?.is_none(), "ref was deleted"); | |
| 94 | − assert!(store.find("main", None)?.is_some(), "referent still exists"); | |
| 93 | + assert!(store.loose_find("HEAD")?.is_none(), "ref was deleted"); | |
| 94 | + assert!(store.loose_find("main")?.is_some(), "referent still exists"); | |
| 95 | 95 | Ok(()) |
| 96 | 96 | } |
| 97 | 97 | |
| @@ -108,7 +108,7 @@ fn delete_ref_with_incorrect_previous_value_fails() { · 10 unmodified lines | ||
| 108 | 108 | previous: Some(Target::Symbolic("refs/heads/main".try_into().unwrap())), |
| 109 | 109 | log: RefLog::Only, |
| 110 | 110 | }, |
| 111 | − name: head.name().into(), | |
| 111 | + name: head.name.clone(), | |
| 112 | 112 | deref: true, |
| 113 | 113 | }), |
| 114 | 114 | Fail::Immediately, |
| @@ -118,9 +118,9 @@ fn delete_ref_with_incorrect_previous_value_fails() { · 3 unmodified lines | ||
| 118 | 118 | |
| 119 | 119 | assert_eq!(err.to_string(), "The reference 'refs/heads/main' should have content ref: refs/heads/main, actual content was 02a7a22d90d7c02fb494ed25551850b868e634f0"); |
| 120 | 120 | // everything stays as is |
| 121 | − let head = store.find_existing("HEAD", None).unwrap(); | |
| 121 | + let head = store.loose_find_existing("HEAD").unwrap(); | |
| 122 | 122 | assert!(head.log_exists().unwrap()); |
| 123 | − let main = store.find_existing("main", None).expect("referent still exists"); | |
| 123 | + let main = store.loose_find_existing("main").expect("referent still exists"); | |
| 124 | 124 | assert!(main.log_exists().unwrap()); |
| 125 | 125 | } |
| 126 | 126 | |
| @@ -137,7 +137,7 @@ fn delete_reflog_only_of_symbolic_no_deref() -> crate::Result { · 10 unmodified lines | ||
| 137 | 137 | previous: Some(Target::Symbolic("refs/heads/main".try_into()?)), |
| 138 | 138 | log: RefLog::Only, |
| 139 | 139 | }, |
| 140 | − name: head.name().into(), | |
| 140 | + name: head.name, | |
| 141 | 141 | deref: false, |
| 142 | 142 | }), |
| 143 | 143 | Fail::Immediately, |
| @@ -145,12 +145,12 @@ fn delete_reflog_only_of_symbolic_no_deref() -> crate::Result { · 1 unmodified line | ||
| 145 | 145 | .commit(&committer())?; |
| 146 | 146 | |
| 147 | 147 | assert_eq!(edits.len(), 1); |
| 148 | − let head = store.find_existing("HEAD", None)?; | |
| 148 | + let head = store.loose_find_existing("HEAD")?; | |
| 149 | 149 | assert!(!head.log_exists().unwrap()); |
| 150 | − let main = store.find_existing("main", None).expect("referent still exists"); | |
| 150 | + let main = store.loose_find_existing("main").expect("referent still exists"); | |
| 151 | 151 | assert!(main.log_exists()?, "log is untouched, too"); |
| 152 | 152 | assert_eq!( |
| 153 | − main.target(), | |
| 153 | + main.target, | |
| 154 | 154 | head.peel_one_level(None).expect("a symref")?.target(), |
| 155 | 155 | "head points to main" |
| 156 | 156 | ); |
| @@ -170,7 +170,7 @@ fn delete_reflog_only_of_symbolic_with_deref() -> crate::Result { · 13 unmodified lines | ||
| 170 | 170 | previous: Some(Target::must_exist()), |
| 171 | 171 | log: RefLog::Only, |
| 172 | 172 | }, |
| 173 | − name: head.name().into(), | |
| 173 | + name: head.name, | |
| 174 | 174 | deref: true, |
| 175 | 175 | }), |
| 176 | 176 | Fail::Immediately, |
| @@ -178,12 +178,12 @@ fn delete_reflog_only_of_symbolic_with_deref() -> crate::Result { · 1 unmodified line | ||
| 178 | 178 | .commit(&committer())?; |
| 179 | 179 | |
| 180 | 180 | assert_eq!(edits.len(), 2); |
| 181 | − let head = store.find_existing("HEAD", None)?; | |
| 181 | + let head = store.loose_find_existing("HEAD")?; | |
| 182 | 182 | assert!(!head.log_exists()?); |
| 183 | − let main = store.find_existing("main", None).expect("referent still exists"); | |
| 183 | + let main = store.loose_find_existing("main").expect("referent still exists"); | |
| 184 | 184 | assert!(!main.log_exists()?, "log is removed"); |
| 185 | 185 | assert_eq!( |
| 186 | − main.target(), | |
| 186 | + main.target, | |
| 187 | 187 | head.peel_one_level(None).expect("a symref")?.target(), |
| 188 | 188 | "head points to main" |
| 189 | 189 | ); |
| @@ -195,7 +195,7 @@ fn delete_reflog_only_of_symbolic_with_deref() -> crate::Result { · 5 unmodified lines | ||
| 195 | 195 | fn delete_broken_ref_that_must_exist_fails_as_it_is_no_valid_ref() { |
| 196 | 196 | let (_keep, store) = empty_store().unwrap(); |
| 197 | 197 | std::fs::write(store.base.join("HEAD"), &b"broken").unwrap(); |
| 198 | − assert!(store.find("HEAD", None).is_err(), "the ref is truly broken"); | |
| 198 | + assert!(store.loose_find("HEAD").is_err(), "the ref is truly broken"); | |
| 199 | 199 | |
| 200 | 200 | let err = store |
| 201 | 201 | .transaction( |
| @@ -222,7 +222,7 @@ fn delete_broken_ref_that_must_exist_fails_as_it_is_no_valid_ref() { · 20 unmodified lines | ||
| 222 | 222 | fn delete_broken_ref_that_may_not_exist_works_even_in_deref_mode() -> crate::Result { |
| 223 | 223 | let (_keep, store) = empty_store()?; |
| 224 | 224 | std::fs::write(store.base.join("HEAD"), &b"broken")?; |
| 225 | − assert!(store.find("HEAD", None).is_err(), "the ref is truly broken"); | |
| 225 | + assert!(store.loose_find("HEAD").is_err(), "the ref is truly broken"); | |
| 226 | 226 | |
| 227 | 227 | let edits = store |
| 228 | 228 | .transaction( |
| @@ -238,7 +238,7 @@ fn delete_broken_ref_that_may_not_exist_works_even_in_deref_mode() -> crate::Res · 9 unmodified lines | ||
| 238 | 238 | ) |
| 239 | 239 | .commit(&committer())?; |
| 240 | 240 | |
| 241 | − assert!(store.find("HEAD", None)?.is_none(), "the ref was deleted"); | |
| 241 | + assert!(store.loose_find("HEAD")?.is_none(), "the ref was deleted"); | |
| 242 | 242 | assert_eq!( |
| 243 | 243 | edits, |
| 244 | 244 | vec![RefEdit { |
| @@ -258,7 +258,7 @@ fn store_write_mode_has_no_effect_and_reflogs_are_always_deleted() -> crate::Res · 13 unmodified lines | ||
| 258 | 258 | for reflog_writemode in &[git_ref::file::WriteReflog::Normal, git_ref::file::WriteReflog::Disable] { |
| 259 | 259 | let (_keep, mut store) = store_writable("make_repo_for_reflog.sh")?; |
| 260 | 260 | store.write_reflog = *reflog_writemode; |
| 261 | − assert!(store.find_existing("HEAD", None)?.log_exists()?,); | |
| 261 | + assert!(store.loose_find_existing("HEAD")?.log_exists()?,); | |
| 262 | 262 | let edits = store |
| 263 | 263 | .transaction( |
| 264 | 264 | Some(RefEdit { |
| @@ -273,7 +273,7 @@ fn store_write_mode_has_no_effect_and_reflogs_are_always_deleted() -> crate::Res · 8 unmodified lines | ||
| 273 | 273 | ) |
| 274 | 274 | .commit(&committer())?; |
| 275 | 275 | assert_eq!(edits.len(), 1); |
| 276 | − assert!(!store.find_existing("HEAD", None)?.log_exists()?, "log was deleted"); | |
| 276 | + assert!(!store.loose_find_existing("HEAD")?.log_exists()?, "log was deleted"); | |
| 277 | 277 | } |
| 278 | 278 | Ok(()) |
| 279 | 279 | } |
| @@ -3,7 +3,7 @@ use crate::{ · 2 unmodified lines | ||
| 3 | 3 | packed::write_packed_refs_with, |
| 4 | 4 | }; |
| 5 | 5 | use git_ref::{packed, PartialName}; |
| 6 | −use std::{convert::TryFrom, path::Path}; | |
| 6 | +use std::convert::TryFrom; | |
| 7 | 7 | |
| 8 | 8 | #[test] |
| 9 | 9 | fn a_lock_file_would_not_be_a_valid_partial_name() { |
| @@ -73,8 +73,8 @@ fn partial_name_to_full_name_conversion_rules_are_applied() -> crate::Result { · 63 unmodified lines | ||
| 73 | 73 | let packed = store.packed()?.expect("packed-refs exists"); |
| 74 | 74 | |
| 75 | 75 | assert_eq!( |
| 76 | − store.loose_find_existing("origin")?.relative_path(), | |
| 77 | − Path::new("refs/remotes/origin/HEAD"), | |
| 76 | + store.loose_find_existing("origin")?.name.as_bstr(), | |
| 77 | + "refs/remotes/origin/HEAD", | |
| 78 | 78 | "a special that only applies to loose refs" |
| 79 | 79 | ); |
| 80 | 80 | assert!( |
| @@ -82,8 +82,8 @@ fn partial_name_to_full_name_conversion_rules_are_applied() -> crate::Result { · 1 unmodified line | ||
| 82 | 82 | "packed refs don't have this special case as they don't store HEADs or symrefs" |
| 83 | 83 | ); |
| 84 | 84 | assert_eq!( |
| 85 | − store.loose_find_existing("HEAD")?.relative_path(), | |
| 86 | − Path::new("HEAD"), | |
| 85 | + store.loose_find_existing("HEAD")?.name.as_bstr(), | |
| 86 | + "HEAD", | |
| 87 | 87 | "HEAD can be found in loose stores" |
| 88 | 88 | ); |
| 89 | 89 | assert!( |
| @@ -9,8 +9,8 @@ quick_error! { · 8 unmodified lines | ||
| 9 | 9 | from() |
| 10 | 10 | source(err) |
| 11 | 11 | } |
| 12 | − MisplacedHead(relative_path: PathBuf) { | |
| 13 | − display("Expected HEAD at '.git/HEAD', got '.git/{}'", relative_path.display()) | |
| 12 | + MisplacedHead(name: crate::object::bstr::BString) { | |
| 13 | + display("Expected HEAD at '.git/HEAD', got '.git/{}'", name) | |
| 14 | 14 | } |
| 15 | 15 | MissingObjectsDirectory(missing: PathBuf) { |
| 16 | 16 | display("Expected an objects directory at '{}'", missing.display()) |
| @@ -42,8 +42,8 @@ pub fn is_git(git_dir: impl AsRef<Path>) -> Result<crate::Kind, Error> { · 25 unmodified lines | ||
| 42 | 42 | { |
| 43 | 43 | let refs = git_ref::file::Store::at(&dot_git, Default::default()); |
| 44 | 44 | let head = refs.loose_find_existing("HEAD")?; |
| 45 | − if head.relative_path() != Path::new("HEAD") { | |
| 46 | − return Err(Error::MisplacedHead(head.into_relative_path())); | |
| 45 | + if head.name().as_bstr() != "HEAD" { | |
| 46 | + return Err(Error::MisplacedHead(head.into_name().into_inner())); | |
| 47 | 47 | } |
| 48 | 48 | } |
| 49 | 49 | |