From f8ac2f79a2bc4828adc6b6e7a15c8d28bd17c241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20St=C4=99pie=C5=84?= Date: Mon, 12 Dec 2022 11:50:27 +0100 Subject: [PATCH 1/4] implement find_prefix for index --- src/index.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/index.rs b/src/index.rs index b2e8dfe5c1..9328b2c258 100644 --- a/src/index.rs +++ b/src/index.rs @@ -596,6 +596,26 @@ impl Index { Ok(Binding::from_raw(&raw as *const _)) } } + + /// Find the first position of any entries matching a prefix. + /// + /// To find the first position of a path inside a given folder, suffix the prefix with a '/'. + pub fn find_prefix(&self, path: &Path) -> Result, Error> { + unsafe { + let mut at_pos: size_t = 0; + let entry_path = path.into_c_string()?; + let result = call!(raw::git_index_find_prefix( + &mut at_pos, + self.raw, + entry_path + )); + if result == 0 { + Ok(Some(at_pos)) + } else { + Ok(None) + } + } + } } impl Binding for Index { @@ -857,6 +877,21 @@ mod tests { assert_eq!(e.path.len(), 6); } + #[test] + fn add_then_find() { + let mut index = Index::new().unwrap(); + let mut e = entry(); + e.path = b"foo/bar".to_vec(); + index.add(&e).unwrap(); + assert_eq!(index.get(0).unwrap().path, b"foo/bar"); + assert_eq!( + index.get_path(Path::new("foo/bar"), 0).unwrap().path, + b"foo/bar" + ); + assert_eq!(index.find_prefix(Path::new("foo/")).unwrap(), Some(0)); + assert_eq!(index.find_prefix(Path::new("empty/")).unwrap(), None); + } + #[test] fn add_frombuffer_then_read() { let (_td, repo) = crate::test::repo_init(); From c1e4ae1c47cd32f71c0976e231fb3112c717612d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20St=C4=99pie=C5=84?= Date: Mon, 12 Dec 2022 12:01:06 +0100 Subject: [PATCH 2/4] add git_index_find_prefix to raw --- libgit2-sys/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 5e943c0d09..87855c85b1 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -2953,6 +2953,11 @@ extern "C" { pub fn git_index_entrycount(entry: *const git_index) -> size_t; pub fn git_index_find(at_pos: *mut size_t, index: *mut git_index, path: *const c_char) -> c_int; + pub fn git_index_find_prefix( + at_pos: *mut size_t, + index: *mut git_index, + prefix: *const c_char, + ) -> c_int; pub fn git_index_free(index: *mut git_index); pub fn git_index_get_byindex(index: *mut git_index, n: size_t) -> *const git_index_entry; pub fn git_index_get_bypath( From 4a67c0ba3ba9d3fc9aac92285ca4b4549be7362c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20St=C4=99pie=C5=84?= Date: Tue, 13 Dec 2022 19:04:55 +0100 Subject: [PATCH 3/4] use generic IntoCString instead of only path as a prefix arg for find_prefix --- src/index.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/index.rs b/src/index.rs index 9328b2c258..69477497c1 100644 --- a/src/index.rs +++ b/src/index.rs @@ -600,10 +600,10 @@ impl Index { /// Find the first position of any entries matching a prefix. /// /// To find the first position of a path inside a given folder, suffix the prefix with a '/'. - pub fn find_prefix(&self, path: &Path) -> Result, Error> { + pub fn find_prefix(&self, prefix: T) -> Result, Error> { unsafe { let mut at_pos: size_t = 0; - let entry_path = path.into_c_string()?; + let entry_path = prefix.into_c_string()?; let result = call!(raw::git_index_find_prefix( &mut at_pos, self.raw, @@ -883,12 +883,15 @@ mod tests { let mut e = entry(); e.path = b"foo/bar".to_vec(); index.add(&e).unwrap(); + let mut e = entry(); + e.path = b"foo2/bar".to_vec(); + index.add(&e).unwrap(); assert_eq!(index.get(0).unwrap().path, b"foo/bar"); assert_eq!( index.get_path(Path::new("foo/bar"), 0).unwrap().path, b"foo/bar" ); - assert_eq!(index.find_prefix(Path::new("foo/")).unwrap(), Some(0)); + assert_eq!(index.find_prefix(Path::new("foo2/")).unwrap(), Some(1)); assert_eq!(index.find_prefix(Path::new("empty/")).unwrap(), None); } From d73c3f841290703fb447d4e76d81ab9187115067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20St=C4=99pie=C5=84?= Date: Mon, 9 Jan 2023 15:37:05 +0100 Subject: [PATCH 4/4] remove GIT_ENOTFOUND check and instead return it as an Err --- src/index.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/index.rs b/src/index.rs index 69477497c1..f214351891 100644 --- a/src/index.rs +++ b/src/index.rs @@ -600,20 +600,16 @@ impl Index { /// Find the first position of any entries matching a prefix. /// /// To find the first position of a path inside a given folder, suffix the prefix with a '/'. - pub fn find_prefix(&self, prefix: T) -> Result, Error> { + pub fn find_prefix(&self, prefix: T) -> Result { + let mut at_pos: size_t = 0; + let entry_path = prefix.into_c_string()?; unsafe { - let mut at_pos: size_t = 0; - let entry_path = prefix.into_c_string()?; - let result = call!(raw::git_index_find_prefix( + try_call!(raw::git_index_find_prefix( &mut at_pos, self.raw, entry_path )); - if result == 0 { - Ok(Some(at_pos)) - } else { - Ok(None) - } + Ok(at_pos) } } } @@ -766,7 +762,7 @@ mod tests { use std::path::Path; use tempfile::TempDir; - use crate::{Index, IndexEntry, IndexTime, Oid, Repository, ResetType}; + use crate::{ErrorCode, Index, IndexEntry, IndexTime, Oid, Repository, ResetType}; #[test] fn smoke() { @@ -891,8 +887,11 @@ mod tests { index.get_path(Path::new("foo/bar"), 0).unwrap().path, b"foo/bar" ); - assert_eq!(index.find_prefix(Path::new("foo2/")).unwrap(), Some(1)); - assert_eq!(index.find_prefix(Path::new("empty/")).unwrap(), None); + assert_eq!(index.find_prefix(Path::new("foo2/")), Ok(1)); + assert_eq!( + index.find_prefix(Path::new("empty/")).unwrap_err().code(), + ErrorCode::NotFound + ); } #[test]