Skip to content

Commit dbb6886

Browse files
committed
change!: use gix-object::Find trait
1 parent 7407fec commit dbb6886

File tree

10 files changed

+61
-80
lines changed

10 files changed

+61
-80
lines changed

gix-ref/src/peel.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
/// A function for use in [`crate::file::ReferenceExt::peel_to_id_in_place()`] to indicate no peeling should happen.
2-
#[allow(clippy::type_complexity)]
3-
pub fn none(
4-
_id: gix_hash::ObjectId,
5-
#[allow(clippy::ptr_arg)] _buf: &mut Vec<u8>,
6-
) -> Result<Option<(gix_object::Kind, &[u8])>, Box<dyn std::error::Error + Send + Sync>> {
7-
Ok(Some((gix_object::Kind::Commit, &[])))
8-
}
9-
101
///
112
pub mod to_id {
123
use std::path::PathBuf;
@@ -26,7 +17,7 @@ pub mod to_id {
2617
#[error("Refusing to follow more than {max_depth} levels of indirection")]
2718
DepthLimitExceeded { max_depth: usize },
2819
#[error("An error occurred when trying to resolve an object a reference points to")]
29-
Find(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),
20+
Find(#[from] gix_object::find::Error),
3021
#[error("Object {oid} as referred to by {name:?} could not be found")]
3122
NotFound { oid: gix_hash::ObjectId, name: BString },
3223
}

gix-ref/src/store/file/raw_ext.rs

+18-17
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ use crate::{
1212
pub trait Sealed {}
1313
impl Sealed for crate::Reference {}
1414

15-
pub type FindObjectFn<'a> = dyn FnMut(
16-
gix_hash::ObjectId,
17-
&mut Vec<u8>,
18-
) -> Result<Option<(gix_object::Kind, &[u8])>, Box<dyn std::error::Error + Send + Sync>>
19-
+ 'a;
20-
2115
/// A trait to extend [Reference][crate::Reference] with functionality requiring a [file::Store].
2216
pub trait ReferenceExt: Sealed {
2317
/// A step towards obtaining forward or reverse iterators on reference logs.
@@ -26,18 +20,22 @@ pub trait ReferenceExt: Sealed {
2620
/// For details, see [`Reference::log_exists()`].
2721
fn log_exists(&self, store: &file::Store) -> bool;
2822

29-
/// For details, see [`Reference::peel_to_id_in_place()`].
23+
/// Follow all symbolic targets this reference might point to and peel the underlying object
24+
/// to the end of the chain, and return it, using `objects` to access them.
25+
///
26+
/// This is useful to learn where this reference is ultimately pointing to.
3027
fn peel_to_id_in_place(
3128
&mut self,
3229
store: &file::Store,
33-
find: &mut FindObjectFn<'_>,
30+
objects: &dyn gix_object::Find,
3431
) -> Result<ObjectId, peel::to_id::Error>;
3532

36-
/// For details, see [`Reference::peel_to_id_in_place()`], with support for a known stable packed buffer.
33+
/// Like [`ReferenceExt::peel_to_id_in_place()`], but with support for a known stable packed buffer
34+
/// to use for resolving symbolic links.
3735
fn peel_to_id_in_place_packed(
3836
&mut self,
3937
store: &file::Store,
40-
find: &mut FindObjectFn<'_>,
38+
objects: &dyn gix_object::Find,
4139
packed: Option<&packed::Buffer>,
4240
) -> Result<ObjectId, peel::to_id::Error>;
4341

@@ -75,18 +73,18 @@ impl ReferenceExt for Reference {
7573
fn peel_to_id_in_place(
7674
&mut self,
7775
store: &file::Store,
78-
find: &mut FindObjectFn<'_>,
76+
objects: &dyn gix_object::Find,
7977
) -> Result<ObjectId, peel::to_id::Error> {
8078
let packed = store.assure_packed_refs_uptodate().map_err(|err| {
8179
peel::to_id::Error::Follow(file::find::existing::Error::Find(file::find::Error::PackedOpen(err)))
8280
})?;
83-
self.peel_to_id_in_place_packed(store, find, packed.as_ref().map(|b| &***b))
81+
self.peel_to_id_in_place_packed(store, objects, packed.as_ref().map(|b| &***b))
8482
}
8583

8684
fn peel_to_id_in_place_packed(
8785
&mut self,
8886
store: &file::Store,
89-
find: &mut FindObjectFn<'_>,
87+
objects: &dyn gix_object::Find,
9088
packed: Option<&packed::Buffer>,
9189
) -> Result<ObjectId, peel::to_id::Error> {
9290
match self.peeled {
@@ -118,10 +116,13 @@ impl ReferenceExt for Reference {
118116
let mut buf = Vec::new();
119117
let mut oid = self.target.try_id().expect("peeled ref").to_owned();
120118
let peeled_id = loop {
121-
let (kind, data) = find(oid, &mut buf)?.ok_or_else(|| peel::to_id::Error::NotFound {
122-
oid,
123-
name: self.name.0.clone(),
124-
})?;
119+
let gix_object::Data { kind, data } =
120+
objects
121+
.try_find(&oid, &mut buf)?
122+
.ok_or_else(|| peel::to_id::Error::NotFound {
123+
oid,
124+
name: self.name.0.clone(),
125+
})?;
125126
match kind {
126127
gix_object::Kind::Tag => {
127128
oid = gix_object::TagRefIter::from_bytes(data).target_id().map_err(|_err| {

gix-ref/src/store/file/transaction/mod.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,18 @@ use crate::{
88
transaction::RefEdit,
99
};
1010

11-
/// A function receiving an object id to resolve, returning its decompressed bytes,
12-
/// used to obtain the peeled object ids for storage in packed-refs files.
13-
///
14-
/// Resolution means to follow tag objects until the end of the chain.
15-
pub type FindObjectFn<'a> = dyn FnMut(
16-
gix_hash::ObjectId,
17-
&mut Vec<u8>,
18-
) -> Result<Option<gix_object::Kind>, Box<dyn std::error::Error + Send + Sync + 'static>>
19-
+ 'a;
20-
2111
/// How to handle packed refs during a transaction
2212
#[derive(Default)]
2313
pub enum PackedRefs<'a> {
2414
/// Only propagate deletions of references. This is the default
2515
#[default]
2616
DeletionsOnly,
2717
/// Propagate deletions as well as updates to references which are peeled, that is contain an object id
28-
DeletionsAndNonSymbolicUpdates(Box<FindObjectFn<'a>>),
18+
DeletionsAndNonSymbolicUpdates(Box<dyn gix_object::Find + 'a>),
2919
/// Propagate deletions as well as updates to references which are peeled, that is contain an object id. Furthermore delete the
3020
/// reference which is originally updated if it exists. If it doesn't, the new value will be written into the packed ref right away.
3121
/// Note that this doesn't affect symbolic references at all, which can't be placed into packed refs.
32-
DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference(Box<FindObjectFn<'a>>),
22+
DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference(Box<dyn gix_object::Find + 'a>),
3323
}
3424

3525
#[derive(Debug)]

gix-ref/src/store/file/transaction/prepare.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -338,12 +338,10 @@ impl<'s, 'p> Transaction<'s, 'p> {
338338
self.packed_transaction = Some(match &mut self.packed_refs {
339339
PackedRefs::DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference(f)
340340
| PackedRefs::DeletionsAndNonSymbolicUpdates(f) => {
341-
transaction.prepare(&mut edits_for_packed_transaction.into_iter(), f)?
341+
transaction.prepare(&mut edits_for_packed_transaction.into_iter(), &**f)?
342342
}
343343
PackedRefs::DeletionsOnly => transaction
344-
.prepare(&mut edits_for_packed_transaction.into_iter(), &mut |_, _| {
345-
unreachable!("BUG: deletions never trigger object lookups")
346-
})?,
344+
.prepare(&mut edits_for_packed_transaction.into_iter(), &gix_object::find::Never)?,
347345
});
348346
}
349347
}

gix-ref/src/store/packed/transaction.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{fmt::Formatter, io::Write};
22

33
use crate::{
44
file,
5-
store_impl::{file::transaction::FindObjectFn, packed, packed::Edit},
5+
store_impl::{packed, packed::Edit},
66
transaction::{Change, RefEdit},
77
Target,
88
};
@@ -44,10 +44,11 @@ impl packed::Transaction {
4444
/// Lifecycle
4545
impl packed::Transaction {
4646
/// Prepare the transaction by checking all edits for applicability.
47+
/// Use `objects` to access objects for the purpose of peeling them - this is only used if packed-refs are involved.
4748
pub fn prepare(
4849
mut self,
4950
edits: &mut dyn Iterator<Item = RefEdit>,
50-
find: &mut FindObjectFn<'_>,
51+
objects: &dyn gix_object::Find,
5152
) -> Result<Self, prepare::Error> {
5253
assert!(self.edits.is_none(), "BUG: cannot call prepare(…) more than once");
5354
let buffer = &self.buffer;
@@ -76,7 +77,7 @@ impl packed::Transaction {
7677
{
7778
let mut next_id = new;
7879
edit.peeled = loop {
79-
let kind = find(next_id, &mut buf)?;
80+
let kind = objects.try_find(&next_id, &mut buf)?.map(|d| d.kind);
8081
match kind {
8182
Some(gix_object::Kind::Tag) => {
8283
next_id = gix_object::TagRefIter::from_bytes(&buf).target_id().map_err(|_| {

gix-ref/tests/file/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,20 @@ fn store_writable(name: &str) -> crate::Result<(gix_testtools::tempfile::TempDir
3131
))
3232
}
3333

34+
struct EmptyCommit;
35+
impl gix_object::Find for EmptyCommit {
36+
fn try_find<'a>(
37+
&self,
38+
_id: &gix_hash::oid,
39+
_buffer: &'a mut Vec<u8>,
40+
) -> Result<Option<gix_object::Data<'a>>, gix_object::find::Error> {
41+
Ok(Some(gix_object::Data {
42+
kind: gix_object::Kind::Commit,
43+
data: &[],
44+
}))
45+
}
46+
}
47+
3448
mod log;
3549
mod reference;
3650
mod store;

gix-ref/tests/file/reference.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ mod reflog {
4747
}
4848

4949
mod peel {
50-
use gix_odb::pack::Find;
51-
use gix_ref::{file::ReferenceExt, peel, Reference};
50+
use gix_ref::{file::ReferenceExt, Reference};
5251

52+
use crate::file::EmptyCommit;
5353
use crate::{file, file::store_with_packed_refs, hex_to_id};
5454

5555
#[test]
@@ -77,11 +77,11 @@ mod peel {
7777
let store = store_with_packed_refs()?;
7878
let mut head: Reference = store.find_loose("HEAD")?.into();
7979
let expected = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03");
80-
assert_eq!(head.peel_to_id_in_place(&store, &mut peel::none)?, expected);
80+
assert_eq!(head.peel_to_id_in_place(&store, &EmptyCommit)?, expected);
8181
assert_eq!(head.target.try_id().map(ToOwned::to_owned), Some(expected));
8282

8383
let mut head = store.find("dt1")?;
84-
assert_eq!(head.peel_to_id_in_place(&store, &mut peel::none)?, expected);
84+
assert_eq!(head.peel_to_id_in_place(&store, &gix_object::find::Never)?, expected);
8585
assert_eq!(head.target.into_id(), expected);
8686
Ok(())
8787
}
@@ -119,23 +119,20 @@ mod peel {
119119
assert_eq!(r.kind(), gix_ref::Kind::Symbolic, "there is something to peel");
120120

121121
let commit = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03");
122-
assert_eq!(r.peel_to_id_in_place(&store, &mut peel::none)?, commit);
122+
assert_eq!(r.peel_to_id_in_place(&store, &EmptyCommit)?, commit);
123123
assert_eq!(r.name.as_bstr(), "refs/remotes/origin/multi-link-target3");
124124

125125
let mut r: Reference = store.find_loose("dt1")?.into();
126126
assert_eq!(
127-
r.peel_to_id_in_place(&store, &mut peel::none)?,
127+
r.peel_to_id_in_place(&store, &EmptyCommit)?,
128128
hex_to_id("4c3f4cce493d7beb45012e478021b5f65295e5a3"),
129129
"points to a tag object without actual object lookup"
130130
);
131131

132132
let odb = gix_odb::at(store.git_dir().join("objects"))?;
133133
let mut r: Reference = store.find_loose("dt1")?.into();
134134
assert_eq!(
135-
r.peel_to_id_in_place(&store, &mut |oid, buf| {
136-
odb.try_find(&oid, buf)
137-
.map(|obj| obj.map(|(obj, _)| (obj.kind, obj.data)))
138-
})?,
135+
r.peel_to_id_in_place(&store, &odb)?,
139136
commit,
140137
"points to the commit with lookup"
141138
);
@@ -151,7 +148,7 @@ mod peel {
151148
assert_eq!(r.name.as_bstr(), "refs/loop-a");
152149

153150
assert!(matches!(
154-
r.peel_to_id_in_place(&store, &mut peel::none).unwrap_err(),
151+
r.peel_to_id_in_place(&store, &gix_object::find::Never).unwrap_err(),
155152
gix_ref::peel::to_id::Error::Cycle { .. }
156153
));
157154
assert_eq!(r.name.as_bstr(), "refs/loop-a", "the ref is not changed on error");

gix-ref/tests/file/transaction/prepare_and_commit/create_or_update/collisions.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use gix_ref::{
77
Target,
88
};
99

10+
use crate::file::EmptyCommit;
1011
use crate::{
1112
file::transaction::prepare_and_commit::{committer, create_at, create_symbolic_at, delete_at, empty_store},
1213
hex_to_id,
@@ -69,14 +70,14 @@ fn packed_refs_lock_is_mandatory_for_multiple_ongoing_transactions_even_if_one_d
6970
let _t1 = store
7071
.transaction()
7172
.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference(
72-
Box::new(|_, _| Ok(Some(gix_object::Kind::Commit))),
73+
Box::new(EmptyCommit),
7374
))
7475
.prepare([create_at(ref_name)], Fail::Immediately, Fail::Immediately)?;
7576

7677
let t2res = store
7778
.transaction()
7879
.prepare([delete_at(ref_name)], Fail::Immediately, Fail::Immediately);
79-
assert_eq!(&t2res.unwrap_err().to_string()[..51], "The lock for the packed-ref file could not be obtai", "if packed-refs are about to be created, other transactions always acquire a packed-refs lock as to not miss anything");
80+
assert_eq!(&t2res.unwrap_err().to_string()[..54], "The lock for the packed-ref file could not be obtained", "if packed-refs are about to be created, other transactions always acquire a packed-refs lock as to not miss anything");
8081
Ok(())
8182
}
8283

@@ -86,7 +87,7 @@ fn conflicting_creation_into_packed_refs() -> crate::Result {
8687
store
8788
.transaction()
8889
.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference(
89-
Box::new(|_, _| Ok(Some(gix_object::Kind::Commit))),
90+
Box::new(EmptyCommit),
9091
))
9192
.prepare(
9293
[
@@ -118,7 +119,7 @@ fn conflicting_creation_into_packed_refs() -> crate::Result {
118119
store
119120
.transaction()
120121
.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference(
121-
Box::new(|_, _| Ok(Some(gix_object::Kind::Commit))),
122+
Box::new(EmptyCommit),
122123
))
123124
.prepare(
124125
[

gix-ref/tests/file/transaction/prepare_and_commit/create_or_update/mod.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::convert::TryInto;
33
use gix_hash::ObjectId;
44
use gix_lock::acquire::Fail;
55
use gix_object::bstr::{BString, ByteSlice};
6-
use gix_object::Find;
76
use gix_ref::{
87
file::{
98
transaction::{self, PackedRefs},
@@ -14,6 +13,7 @@ use gix_ref::{
1413
Target,
1514
};
1615

16+
use crate::file::EmptyCommit;
1717
use crate::{
1818
file::{
1919
store_with_packed_refs, store_writable,
@@ -713,7 +713,7 @@ fn packed_refs_creation_with_packed_refs_mode_prune_removes_original_loose_refs(
713713
let edits = store
714714
.transaction()
715715
.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference(
716-
Box::new(move |oid, buf| odb.try_find(&oid, buf).map(|obj| obj.map(|obj| obj.kind))),
716+
Box::new(odb),
717717
))
718718
.prepare(
719719
store
@@ -782,9 +782,7 @@ fn packed_refs_creation_with_packed_refs_mode_leave_keeps_original_loose_refs()
782782

783783
let edits = store
784784
.transaction()
785-
.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdates(Box::new(|_, _| {
786-
Ok(Some(gix_object::Kind::Commit))
787-
})))
785+
.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdates(Box::new(EmptyCommit)))
788786
.prepare(edits, Fail::Immediately, Fail::Immediately)?
789787
.commit(committer().to_ref())?;
790788
assert_eq!(

gix-ref/tests/file/worktree.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::{cmp::Ordering, path::PathBuf};
22

3-
use gix_object::Find;
43
use gix_ref::{file::ReferenceExt, Reference};
54
use gix_testtools::Creation;
65

@@ -61,13 +60,7 @@ fn into_peel(
6160
store: &gix_ref::file::Store,
6261
odb: gix_odb::Handle,
6362
) -> impl Fn(gix_ref::Reference) -> gix_hash::ObjectId + '_ {
64-
move |mut r: gix_ref::Reference| {
65-
r.peel_to_id_in_place(store, &mut |id, buf| {
66-
let data = odb.try_find(&id, buf)?;
67-
Ok(data.map(|d| (d.kind, d.data)))
68-
})
69-
.unwrap()
70-
}
63+
move |mut r: gix_ref::Reference| r.peel_to_id_in_place(store, &odb).unwrap()
7164
}
7265

7366
enum Mode {
@@ -205,6 +198,7 @@ mod writable {
205198
FullName, FullNameRef, Target,
206199
};
207200

201+
use crate::file::EmptyCommit;
208202
use crate::{
209203
file::{
210204
transaction::prepare_and_commit::committer,
@@ -232,9 +226,7 @@ mod writable {
232226
let (store, _odb, _tmp) = main_store(packed, Mode::Write)?;
233227
let mut t = store.transaction();
234228
if packed {
235-
t = t.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdates(Box::new(|_, _| {
236-
Ok(Some(gix_object::Kind::Commit))
237-
})));
229+
t = t.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdates(Box::new(EmptyCommit)));
238230
}
239231

240232
let edits = t
@@ -514,9 +506,7 @@ mod writable {
514506

515507
let mut t = store.transaction();
516508
if packed {
517-
t = t.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdates(Box::new(|_, _| {
518-
Ok(Some(gix_object::Kind::Commit))
519-
})));
509+
t = t.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdates(Box::new(EmptyCommit)));
520510
}
521511

522512
let edits = t

0 commit comments

Comments
 (0)