summaryrefslogtreecommitdiffstats
path: root/vendor/gix/src/repository/object.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/gix/src/repository/object.rs
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix/src/repository/object.rs')
-rw-r--r--vendor/gix/src/repository/object.rs105
1 files changed, 87 insertions, 18 deletions
diff --git a/vendor/gix/src/repository/object.rs b/vendor/gix/src/repository/object.rs
index 787dcda4e..c156971d0 100644
--- a/vendor/gix/src/repository/object.rs
+++ b/vendor/gix/src/repository/object.rs
@@ -2,11 +2,13 @@
use std::{convert::TryInto, ops::DerefMut};
use gix_hash::ObjectId;
-use gix_odb::{Find, FindExt, Write};
+use gix_macros::momo;
+use gix_odb::{Find, FindExt, Header, HeaderExt, Write};
use gix_ref::{
transaction::{LogChange, PreviousValue, RefLog},
FullName,
};
+use smallvec::SmallVec;
use crate::{commit, ext::ObjectIdExt, object, tag, Id, Object, Reference, Tree};
@@ -21,6 +23,7 @@ impl crate::Repository {
///
/// In order to get the kind of the object, is must be fully decoded from storage if it is packed with deltas.
/// Loose object could be partially decoded, even though that's not implemented.
+ #[momo]
pub fn find_object(&self, id: impl Into<ObjectId>) -> Result<Object<'_>, object::find::existing::Error> {
let id = id.into();
if id == gix_hash::ObjectId::empty_tree(self.object_hash()) {
@@ -32,11 +35,46 @@ impl crate::Repository {
});
}
let mut buf = self.free_buf();
- let kind = self.objects.find(id, &mut buf)?.kind;
+ let kind = self.objects.find(&id, &mut buf)?.kind;
Ok(Object::from_data(id, kind, buf, self))
}
+ /// Obtain information about an object without fully decoding it, or fail if the object doesn't exist.
+ ///
+ /// Note that despite being cheaper than [`Self::find_object()`], there is still some effort traversing delta-chains.
+ #[doc(alias = "read_header", alias = "git2")]
+ #[momo]
+ pub fn find_header(&self, id: impl Into<ObjectId>) -> Result<gix_odb::find::Header, object::find::existing::Error> {
+ let id = id.into();
+ if id == gix_hash::ObjectId::empty_tree(self.object_hash()) {
+ return Ok(gix_odb::find::Header::Loose {
+ kind: gix_object::Kind::Tree,
+ size: 0,
+ });
+ }
+ self.objects.header(id)
+ }
+
+ /// Obtain information about an object without fully decoding it, or `None` if the object doesn't exist.
+ ///
+ /// Note that despite being cheaper than [`Self::try_find_object()`], there is still some effort traversing delta-chains.
+ #[momo]
+ pub fn try_find_header(
+ &self,
+ id: impl Into<ObjectId>,
+ ) -> Result<Option<gix_odb::find::Header>, object::find::Error> {
+ let id = id.into();
+ if id == gix_hash::ObjectId::empty_tree(self.object_hash()) {
+ return Ok(Some(gix_odb::find::Header::Loose {
+ kind: gix_object::Kind::Tree,
+ size: 0,
+ }));
+ }
+ self.objects.try_header(&id).map_err(Into::into)
+ }
+
/// Try to find the object with `id` or return `None` if it wasn't found.
+ #[momo]
pub fn try_find_object(&self, id: impl Into<ObjectId>) -> Result<Option<Object<'_>>, object::find::Error> {
let id = id.into();
if id == gix_hash::ObjectId::empty_tree(self.object_hash()) {
@@ -49,7 +87,7 @@ impl crate::Repository {
}
let mut buf = self.free_buf();
- match self.objects.try_find(id, &mut buf)? {
+ match self.objects.try_find(&id, &mut buf)? {
Some(obj) => {
let kind = obj.kind;
Ok(Some(Object::from_data(id, kind, buf, self)))
@@ -76,15 +114,19 @@ impl crate::Repository {
/// we avoid writing duplicate objects using slow disks that will eventually have to be garbage collected.
pub fn write_object(&self, object: impl gix_object::WriteTo) -> Result<Id<'_>, object::write::Error> {
let mut buf = self.shared_empty_buf();
- object.write_to(buf.deref_mut())?;
+ object.write_to(buf.deref_mut()).expect("write to memory works");
- let oid = gix_object::compute_hash(self.object_hash(), object.kind(), &buf);
- if self.objects.contains(oid) {
+ self.write_object_inner(&buf, object.kind())
+ }
+
+ fn write_object_inner(&self, buf: &[u8], kind: gix_object::Kind) -> Result<Id<'_>, object::write::Error> {
+ let oid = gix_object::compute_hash(self.object_hash(), kind, buf);
+ if self.objects.contains(&oid) {
return Ok(oid.attach(self));
}
self.objects
- .write_buf(object.kind(), &buf)
+ .write_buf(kind, buf)
.map(|oid| oid.attach(self))
.map_err(Into::into)
}
@@ -93,14 +135,16 @@ impl crate::Repository {
///
/// We avoid writing duplicate objects to slow disks that will eventually have to be garbage collected by
/// pre-hashing the data, and checking if the object is already present.
+ #[momo]
pub fn write_blob(&self, bytes: impl AsRef<[u8]>) -> Result<Id<'_>, object::write::Error> {
let bytes = bytes.as_ref();
let oid = gix_object::compute_hash(self.object_hash(), gix_object::Kind::Blob, bytes);
- if self.objects.contains(oid) {
+ if self.objects.contains(&oid) {
return Ok(oid.attach(self));
}
self.objects
.write_buf(gix_object::Kind::Blob, bytes)
+ .map_err(Into::into)
.map(|oid| oid.attach(self))
}
@@ -115,14 +159,20 @@ impl crate::Repository {
mut bytes: impl std::io::Read + std::io::Seek,
) -> Result<Id<'_>, object::write::Error> {
let mut buf = self.shared_empty_buf();
- std::io::copy(&mut bytes, buf.deref_mut())?;
- let oid = gix_object::compute_hash(self.object_hash(), gix_object::Kind::Blob, &buf);
- if self.objects.contains(oid) {
+ std::io::copy(&mut bytes, buf.deref_mut()).expect("write to memory works");
+
+ self.write_blob_stream_inner(&buf)
+ }
+
+ fn write_blob_stream_inner(&self, buf: &[u8]) -> Result<Id<'_>, object::write::Error> {
+ let oid = gix_object::compute_hash(self.object_hash(), gix_object::Kind::Blob, buf);
+ if self.objects.contains(&oid) {
return Ok(oid.attach(self));
}
self.objects
- .write_buf(gix_object::Kind::Blob, &buf)
+ .write_buf(gix_object::Kind::Blob, buf)
+ .map_err(Into::into)
.map(|oid| oid.attach(self))
}
@@ -131,6 +181,7 @@ impl crate::Repository {
///
/// It will be created with `constraint` which is most commonly to [only create it][PreviousValue::MustNotExist]
/// or to [force overwriting a possibly existing tag](PreviousValue::Any).
+ #[momo]
pub fn tag(
&self,
name: impl AsRef<str>,
@@ -168,6 +219,25 @@ impl crate::Repository {
Name: TryInto<FullName, Error = E>,
commit::Error: From<E>,
{
+ self.commit_as_inner(
+ committer.into(),
+ author.into(),
+ reference.try_into()?,
+ message.as_ref(),
+ tree.into(),
+ parents.into_iter().map(Into::into).collect(),
+ )
+ }
+
+ fn commit_as_inner(
+ &self,
+ committer: gix_actor::SignatureRef<'_>,
+ author: gix_actor::SignatureRef<'_>,
+ reference: FullName,
+ message: &str,
+ tree: ObjectId,
+ parents: SmallVec<[gix_hash::ObjectId; 1]>,
+ ) -> Result<Id<'_>, commit::Error> {
use gix_ref::{
transaction::{Change, RefEdit},
Target,
@@ -175,14 +245,13 @@ impl crate::Repository {
// TODO: possibly use CommitRef to save a few allocations (but will have to allocate for object ids anyway.
// This can be made vastly more efficient though if we wanted to, so we lie in the API
- let reference = reference.try_into()?;
let commit = gix_object::Commit {
- message: message.as_ref().into(),
- tree: tree.into(),
- author: author.into().to_owned(),
- committer: committer.into().to_owned(),
+ message: message.into(),
+ tree,
+ author: author.into(),
+ committer: committer.into(),
encoding: None,
- parents: parents.into_iter().map(|id| id.into()).collect(),
+ parents,
extra_headers: Default::default(),
};