Skip to content

Commit

Permalink
Merge pull request #981 from paulvandermeijs/add-git_blame_buffer
Browse files Browse the repository at this point in the history
Add binding for `git_blame_buffer`
  • Loading branch information
ehuss committed Aug 26, 2023
2 parents 19b6d05 + 18f8ad1 commit 4570c39
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
6 changes: 6 additions & 0 deletions libgit2-sys/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3406,6 +3406,12 @@ extern "C" {
) -> c_int;

// blame
pub fn git_blame_buffer(
out: *mut *mut git_blame,
reference: *mut git_blame,
buffer: *const c_char,
buffer_len: size_t,
) -> c_int;
pub fn git_blame_file(
out: *mut *mut git_blame,
repo: *mut git_repository,
Expand Down
32 changes: 29 additions & 3 deletions src/blame.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::util::{self, Binding};
use crate::{raw, signature, Oid, Repository, Signature};
use crate::{raw, signature, Error, Oid, Repository, Signature};
use libc::c_char;
use std::iter::FusedIterator;
use std::marker;
use std::mem;
use std::ops::Range;
use std::path::Path;
use std::{marker, ptr};

/// Opaque structure to hold blame results.
pub struct Blame<'repo> {
Expand All @@ -30,6 +31,24 @@ pub struct BlameIter<'blame> {
}

impl<'repo> Blame<'repo> {
/// Get blame data for a file that has been modified in memory.
///
/// Lines that differ between the buffer and the committed version are
/// marked as having a zero OID for their final_commit_id.
pub fn blame_buffer(&self, buffer: &[u8]) -> Result<Blame<'_>, Error> {
let mut raw = ptr::null_mut();

unsafe {
try_call!(raw::git_blame_buffer(
&mut raw,
self.raw,
buffer.as_ptr() as *const c_char,
buffer.len()
));
Ok(Binding::from_raw(raw))
}
}

/// Gets the number of hunks that exist in the blame structure.
pub fn len(&self) -> usize {
unsafe { raw::git_blame_get_hunk_count(self.raw) as usize }
Expand Down Expand Up @@ -348,6 +367,13 @@ mod tests {
assert_eq!(hunk.final_start_line(), 1);
assert_eq!(hunk.path(), Some(Path::new("foo/bar")));
assert_eq!(hunk.lines_in_hunk(), 0);
assert!(!hunk.is_boundary())
assert!(!hunk.is_boundary());

let blame_buffer = blame.blame_buffer("\n".as_bytes()).unwrap();
let line = blame_buffer.get_line(1).unwrap();

assert_eq!(blame_buffer.len(), 2);
assert_eq!(blame_buffer.iter().count(), 2);
assert!(line.final_commit_id().is_zero());
}
}

0 comments on commit 4570c39

Please sign in to comment.