History

[ref] refactor

Sebastian Thiel committed 5 years ago

Commit e26c72f1 parent f4bb7a019 files · +167 −226Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t