@@ -78,7 +78,7 @@ pub trait OdbBackend {
7878 /// Only the first `oid_prefix_len * 4` bits of `oid_prefix` are set.
7979 /// The remaining `(GIT_OID_SHA1_HEXSIZE - oid_prefix_len) * 4` bits are set to 0.
8080 ///
81- /// If an implementation returns `Ok(())`, `oid`, `data`, and `object_type` SHOULD be set to the
81+ /// If an implementation returns `Ok(())`, `oid`, `data`, and `object_type` MUST be set to the
8282 /// full object ID, the object type, and the contents of the object respectively.
8383 ///
8484 /// [`OdbBackendAllocation`]s SHOULD be created using `ctx` (see
@@ -112,7 +112,7 @@ pub trait OdbBackend {
112112 ///
113113 /// # Implementation notes
114114 ///
115- /// If an implementation returns `Ok(())`, `length` and `object_type` SHOULD be set to the
115+ /// If an implementation returns `Ok(())`, `length` and `object_type` MUST be set to the
116116 /// length of the object's contents and the object type respectively.
117117 ///
118118 /// # Errors
@@ -155,6 +155,36 @@ pub trait OdbBackend {
155155 unimplemented ! ( "OdbBackend::exists" )
156156 }
157157
158+ /// Check if an object exists based on a prefix of its [`Oid`].
159+ ///
160+ /// Corresponds to the `exists_prefix` function of [`git_odb_backend`].
161+ /// Requires that [`SupportedOperations::EXISTS_PREFIX`] is present in the value returned from
162+ /// [`supported_operations`] to expose it to libgit2.
163+ ///
164+ /// The default implementation of this method panics.
165+ ///
166+ /// # Implementation notes
167+ ///
168+ /// Only the first `oid_prefix_len * 4` bits of `oid_prefix` are set.
169+ /// The remaining `(GIT_OID_SHA1_HEXSIZE - oid_prefix_len) * 4` bits are set to 0.
170+ ///
171+ /// If an implementation returns `Ok(oid)`, `oid` SHOULD be the full Oid of the object.
172+ ///
173+ /// # Errors
174+ ///
175+ /// See [`OdbBackend::exists`].
176+ ///
177+ /// [`git_odb_backend`]: raw::git_odb_backend
178+ /// [`supported_operations`]: Self::supported_operations
179+ fn exists_prefix (
180+ & mut self ,
181+ ctx : & OdbBackendContext ,
182+ oid_prefix : Oid ,
183+ oid_prefix_length : usize ,
184+ ) -> Result < Oid , Error > {
185+ unimplemented ! ( "OdbBackend::exists_prefix" )
186+ }
187+
158188 // TODO: fn write()
159189 // TODO: fn writestream()
160190 // TODO: fn readstream()
@@ -351,6 +381,7 @@ impl<'a, B: OdbBackend> CustomOdbBackend<'a, B> {
351381 op_if ! ( read_prefix if READ_PREFIX ) ;
352382 op_if ! ( read_header if READ_HEADER ) ;
353383 op_if ! ( exists if EXISTS ) ;
384+ op_if ! ( exists_prefix if EXISTS_PREFIX ) ;
354385
355386 backend. free = Some ( Backend :: < B > :: free) ;
356387 }
@@ -480,6 +511,24 @@ impl<B: OdbBackend> Backend<B> {
480511 0
481512 }
482513 }
514+
515+ extern "C" fn exists_prefix (
516+ oid_ptr : * mut raw:: git_oid ,
517+ backend_ptr : * mut raw:: git_odb_backend ,
518+ oid_prefix_ptr : * const raw:: git_oid ,
519+ oid_prefix_len : size_t
520+ ) -> c_int {
521+ let backend = unsafe { backend_ptr. cast :: < Self > ( ) . as_mut ( ) . unwrap ( ) } ;
522+ let oid_prefix = unsafe { Oid :: from_raw ( oid_prefix_ptr) } ;
523+ let oid = unsafe { oid_ptr. cast :: < Oid > ( ) . as_mut ( ) . unwrap ( ) } ;
524+
525+ let context = OdbBackendContext { backend_ptr } ;
526+ * oid = match backend. inner . exists_prefix ( & context, oid_prefix, oid_prefix_len) {
527+ Err ( e) => return unsafe { e. raw_set_git_error ( ) } ,
528+ Ok ( x) => x,
529+ } ;
530+ raw:: GIT_OK
531+ }
483532
484533 extern "C" fn free ( backend : * mut raw:: git_odb_backend ) {
485534 let inner = unsafe { Box :: from_raw ( backend. cast :: < Self > ( ) ) } ;
0 commit comments