Skip to content

Commit 68a709e

Browse files
committed
Use new oid where possible in git-odb (#63)
1 parent eecd664 commit 68a709e

File tree

23 files changed

+92
-72
lines changed

23 files changed

+92
-72
lines changed

experiments/object-access/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ fn do_gitoxide(hashes: &[String], objects_dir: &Path) -> anyhow::Result<u64> {
117117
let mut bytes = 0u64;
118118
for hash in hashes {
119119
let hash: git_hash::ObjectId = hash.parse()?;
120-
let obj = odb.locate(hash.to_borrowed(), &mut buf)?.expect("object must exist");
120+
let obj = odb.locate(hash, &mut buf)?.expect("object must exist");
121121
bytes += obj.size() as u64;
122122
}
123123
Ok(bytes)
@@ -131,7 +131,7 @@ fn do_parallel_gitoxide(hashes: &[String], objects_dir: &Path) -> anyhow::Result
131131
.par_iter()
132132
.try_for_each_init::<_, _, _, anyhow::Result<_>>(Vec::new, |mut buf, hash| {
133133
let hash: git_hash::ObjectId = hash.parse()?;
134-
let obj = odb.locate(hash.to_borrowed(), &mut buf)?.expect("object must exist");
134+
let obj = odb.locate(hash, &mut buf)?.expect("object must exist");
135135
bytes.fetch_add(obj.size() as u64, std::sync::atomic::Ordering::Relaxed);
136136
Ok(())
137137
})?;

git-hash/src/borrowed.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::{
1111
pub struct Id<'a>(&'a [u8; SIZE_OF_SHA1_DIGEST]);
1212

1313
/// A borrowed reference to a hash identifying objects.
14-
#[derive(Hash)]
14+
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
1515
#[repr(transparent)]
1616
#[allow(non_camel_case_types)]
1717
#[cfg_attr(feature = "serde1", derive(serde::Serialize))]
@@ -74,6 +74,30 @@ impl oid {
7474
}
7575
}
7676

77+
/// Sha1 specific methods
78+
impl oid {
79+
/// Returns an array with a hexadecimal encoded version of the Sha1 hash this `Id` represents.
80+
///
81+
/// **Panics** if this is not a Sha1 hash, as identifiable by [`Id::kind()`].
82+
pub fn to_sha1_hex(&self) -> [u8; SIZE_OF_SHA1_DIGEST * 2] {
83+
let mut buf = [0u8; SIZE_OF_SHA1_DIGEST * 2];
84+
hex::encode_to_slice(&self.bytes, &mut buf).expect("to count correctly");
85+
buf
86+
}
87+
88+
/// Returns the bytes making up the Sha1.
89+
///
90+
/// **Panics** if this is not a Sha1 hash, as identifiable by [`Id::kind()`].
91+
pub fn sha1(&self) -> &[u8; SIZE_OF_SHA1_DIGEST] {
92+
self.bytes.try_into().expect("correctly sized slice")
93+
}
94+
95+
/// Returns a Sha1 digest with all bytes being initialized to zero.
96+
pub fn null_sha1() -> &'static Self {
97+
oid::from([0u8; SIZE_OF_SHA1_DIGEST].as_ref())
98+
}
99+
}
100+
77101
impl AsRef<oid> for &oid {
78102
fn as_ref(&self) -> &oid {
79103
self

git-hash/src/owned.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,19 @@ impl From<[u8; SIZE_OF_SHA1_DIGEST]> for ObjectId {
9393
}
9494
}
9595

96-
// TODO: remove this - what do we deref to if there are multiple hash sizes?
96+
impl From<&crate::borrowed::oid> for ObjectId {
97+
fn from(v: &oid) -> Self {
98+
match v.kind() {
99+
crate::Kind::Sha1 => ObjectId::from_20_bytes(v.as_bytes()),
100+
}
101+
}
102+
}
103+
97104
impl Deref for ObjectId {
98-
type Target = [u8; SIZE_OF_SHA1_DIGEST];
105+
type Target = oid;
99106

100107
fn deref(&self) -> &Self::Target {
101-
&self.0
108+
self.as_ref()
102109
}
103110
}
104111

git-object/src/borrowed/tree.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub struct Entry<'a> {
2929
pub filename: &'a BStr,
3030
/// The id of the object representing the entry.
3131
#[cfg_attr(feature = "serde1", serde(borrow))]
32-
pub oid: git_hash::borrowed::Id<'a>,
32+
pub oid: &'a git_hash::oid,
3333
}
3434

3535
impl<'a> Tree<'a> {
@@ -68,7 +68,7 @@ fn parse_entry(i: &[u8]) -> IResult<&[u8], Entry<'_>, Error> {
6868
Entry {
6969
mode,
7070
filename: filename.as_bstr(),
71-
oid: git_hash::borrowed::Id::try_from(oid).expect("we counted exactly 20 bytes"),
71+
oid: git_hash::oid::try_from(oid).expect("we counted exactly 20 bytes"),
7272
},
7373
))
7474
}

git-object/src/owned/tree.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl Tree {
6969
out.write_all(&filename)?;
7070
out.write_all(&[b'\0'])?;
7171

72-
out.write_all(&oid[..])?;
72+
out.write_all(oid.as_bytes())?;
7373
}
7474
Ok(())
7575
}

git-object/tests/borrowed/tree.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mod from_bytes {
1111
<[u8; 20]>::from_hex(hex).expect("40 bytes hex sha")
1212
}
1313

14-
pub fn as_id(id: &[u8; 20]) -> git_hash::borrowed::Id {
14+
pub fn as_id(id: &[u8; 20]) -> &git_hash::oid {
1515
id.into()
1616
}
1717

git-odb/src/borrowed.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ pub mod verify {
4646
/// Compute the checksum of `self` and compare it with the `desired` hash.
4747
/// If the hashes do not match, an [`Error`] is returned, containing the actual
4848
/// hash of `self`.
49-
pub fn verify_checksum(&self, desired: git_hash::borrowed::Id<'_>) -> Result<(), Error> {
49+
pub fn verify_checksum(&self, desired: impl AsRef<git_hash::oid>) -> Result<(), Error> {
50+
let desired = desired.as_ref();
5051
let mut sink = hash::Write::new(io::sink(), desired.kind());
5152

5253
loose::object::header::encode(self.kind, self.data.len() as u64, &mut sink).expect("hash to always work");
5354
sink.hash.update(&self.data);
5455

5556
let actual_id = git_hash::ObjectId::from(sink.hash.digest());
56-
if desired != actual_id.to_borrowed() {
57+
if desired != actual_id.as_ref() {
5758
return Err(Error::ChecksumMismatch {
5859
desired: desired.into(),
5960
actual: actual_id,

git-odb/src/compound/locate.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ pub enum Error {
1111
}
1212

1313
impl compound::Db {
14-
/// Find an object as identified by [`id`][git_hash::borrowed::Id] and store its data in full in the provided `buffer`.
14+
/// Find an object as identified by [`ObjectId`][git_hash::ObjectId] and store its data in full in the provided `buffer`.
1515
/// This will search the object in all contained object databases.
1616
pub fn locate<'a>(
1717
&self,
18-
id: git_hash::borrowed::Id<'_>,
18+
id: impl AsRef<git_hash::oid>,
1919
buffer: &'a mut Vec<u8>,
2020
) -> Result<Option<compound::Object<'a>>, Error> {
21+
let id = id.as_ref();
2122
for pack in &self.packs {
2223
if let Some(idx) = pack.internal_locate_index(id) {
2324
let object = pack.internal_get_object_by_index(idx, buffer, &mut pack::cache::Noop)?;

git-odb/src/compound/object.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub mod verify {
6969

7070
impl<'a> Object<'a> {
7171
/// Assert whether the actual checksum of this object matches the `desired` one.
72-
pub fn verify_checksum(&mut self, desired: git_hash::borrowed::Id<'_>) -> Result<(), Error> {
72+
pub fn verify_checksum(&mut self, desired: impl AsRef<git_hash::oid>) -> Result<(), Error> {
7373
match self {
7474
Object::Borrowed(object) => object.verify_checksum(desired).map_err(Into::into),
7575
Object::Loose(object) => object.verify_checksum(desired).map_err(Into::into),

git-odb/src/loose/db/locate.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ pub enum Error {
2626
impl Db {
2727
const OPEN_ACTION: &'static str = "open";
2828

29-
/// Return the object identified by the given [`id][git_hash::borrowed::Id] if present in this database.
29+
/// Return the object identified by the given [`ObjectId`][git_hash::ObjectId] if present in this database.
3030
///
3131
/// Returns `Err` if there was an error locating or reading the object. Returns `Ok<None>` if
3232
/// there was no such object.
33-
pub fn locate(&self, id: git_hash::borrowed::Id<'_>) -> Result<Option<Object>, Error> {
34-
match self.locate_inner(id) {
33+
pub fn locate(&self, id: impl AsRef<git_hash::oid>) -> Result<Option<Object>, Error> {
34+
match self.locate_inner(id.as_ref()) {
3535
Ok(obj) => Ok(Some(obj)),
3636
Err(err) => match err {
3737
Error::Io {
@@ -54,7 +54,7 @@ impl Db {
5454
}
5555
}
5656

57-
fn locate_inner(&self, id: git_hash::borrowed::Id<'_>) -> Result<Object, Error> {
57+
fn locate_inner(&self, id: &git_hash::oid) -> Result<Object, Error> {
5858
let path = sha1_path(id, self.path.clone());
5959

6060
let mut inflate = zlib::Inflate::default();

0 commit comments

Comments
 (0)