Skip to content

Commit 18f8ad1

Browse files
Add binding for git_blame_buffer
1 parent 7f21181 commit 18f8ad1

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

libgit2-sys/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -3406,6 +3406,12 @@ extern "C" {
34063406
) -> c_int;
34073407

34083408
// blame
3409+
pub fn git_blame_buffer(
3410+
out: *mut *mut git_blame,
3411+
reference: *mut git_blame,
3412+
buffer: *const c_char,
3413+
buffer_len: size_t,
3414+
) -> c_int;
34093415
pub fn git_blame_file(
34103416
out: *mut *mut git_blame,
34113417
repo: *mut git_repository,

src/blame.rs

+29-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::util::{self, Binding};
2-
use crate::{raw, signature, Oid, Repository, Signature};
2+
use crate::{raw, signature, Error, Oid, Repository, Signature};
3+
use libc::c_char;
34
use std::iter::FusedIterator;
4-
use std::marker;
55
use std::mem;
66
use std::ops::Range;
77
use std::path::Path;
8+
use std::{marker, ptr};
89

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

3233
impl<'repo> Blame<'repo> {
34+
/// Get blame data for a file that has been modified in memory.
35+
///
36+
/// Lines that differ between the buffer and the committed version are
37+
/// marked as having a zero OID for their final_commit_id.
38+
pub fn blame_buffer(&self, buffer: &[u8]) -> Result<Blame<'_>, Error> {
39+
let mut raw = ptr::null_mut();
40+
41+
unsafe {
42+
try_call!(raw::git_blame_buffer(
43+
&mut raw,
44+
self.raw,
45+
buffer.as_ptr() as *const c_char,
46+
buffer.len()
47+
));
48+
Ok(Binding::from_raw(raw))
49+
}
50+
}
51+
3352
/// Gets the number of hunks that exist in the blame structure.
3453
pub fn len(&self) -> usize {
3554
unsafe { raw::git_blame_get_hunk_count(self.raw) as usize }
@@ -348,6 +367,13 @@ mod tests {
348367
assert_eq!(hunk.final_start_line(), 1);
349368
assert_eq!(hunk.path(), Some(Path::new("foo/bar")));
350369
assert_eq!(hunk.lines_in_hunk(), 0);
351-
assert!(!hunk.is_boundary())
370+
assert!(!hunk.is_boundary());
371+
372+
let blame_buffer = blame.blame_buffer("\n".as_bytes()).unwrap();
373+
let line = blame_buffer.get_line(1).unwrap();
374+
375+
assert_eq!(blame_buffer.len(), 2);
376+
assert_eq!(blame_buffer.iter().count(), 2);
377+
assert!(line.final_commit_id().is_zero());
352378
}
353379
}

0 commit comments

Comments
 (0)