diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 420ca6d7d3..3de6881842 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -2205,6 +2205,13 @@ extern "C" { id: *const git_oid, kind: git_object_t, ) -> c_int; + pub fn git_object_lookup_prefix( + dest: *mut *mut git_object, + repo: *mut git_repository, + id: *const git_oid, + len: size_t, + kind: git_object_t, + ) -> c_int; pub fn git_object_type(obj: *const git_object) -> git_object_t; pub fn git_object_peel( peeled: *mut *mut git_object, diff --git a/src/repo.rs b/src/repo.rs index 6d3b20f8f8..5026923a4e 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1459,6 +1459,25 @@ impl Repository { } } + /// Lookup a reference to one of the objects by id prefix in a repository. + pub fn find_object_by_prefix( + &self, + prefix_hash: &str, + kind: Option, + ) -> Result, Error> { + let mut raw = ptr::null_mut(); + unsafe { + try_call!(raw::git_object_lookup_prefix( + &mut raw, + self.raw(), + Oid::from_str(prefix_hash)?.raw(), + prefix_hash.len(), + kind + )); + Ok(Binding::from_raw(raw)) + } + } + /// Create a new direct reference. /// /// This function will return an error if a reference already exists with @@ -3678,6 +3697,17 @@ mod tests { assert_eq!(repo.head().unwrap().target().unwrap(), main_oid); } + #[test] + fn smoke_find_object_by_prefix() { + let (_td, repo) = crate::test::repo_init(); + let head = repo.head().unwrap().target().unwrap(); + let head = repo.find_commit(head).unwrap(); + let head_id = head.id(); + let head_prefix = &head_id.to_string()[..7]; + let obj = repo.find_object_by_prefix(head_prefix, None).unwrap(); + assert_eq!(obj.id(), head_id); + } + /// create the following: /// /---o4 /// /---o3