@@ -106,11 +106,20 @@ impl<'blame> BlameHunk<'blame> {
106106 unsafe { Oid :: from_raw ( & ( * self . raw ) . final_commit_id ) }
107107 }
108108
109- /// Returns signature of the commit.
109+ /// Returns signature for the author of the final commit.
110+ ///
111+ /// The final commit is the one identified by [Self::final_commit_id()].
110112 pub fn final_signature ( & self ) -> Signature < ' _ > {
111113 unsafe { signature:: from_raw_const ( self , ( * self . raw ) . final_signature ) }
112114 }
113115
116+ /// Returns signature for the committer of the final commit.
117+ ///
118+ /// The final commit is the one identified by [Self::final_commit_id()].
119+ pub fn final_committer ( & self ) -> Signature < ' _ > {
120+ unsafe { signature:: from_raw_const ( self , ( * self . raw ) . final_committer ) }
121+ }
122+
114123 /// Returns line number where this hunk begins.
115124 ///
116125 /// Note that the start line is counting from 1.
@@ -127,11 +136,20 @@ impl<'blame> BlameHunk<'blame> {
127136 unsafe { Oid :: from_raw ( & ( * self . raw ) . orig_commit_id ) }
128137 }
129138
130- /// Returns signature of the commit.
139+ /// Returns signature of the author of the original commit.
140+ ///
141+ /// The original commit is the one identified by [Self::orig_commit_id()].
131142 pub fn orig_signature ( & self ) -> Signature < ' _ > {
132143 unsafe { signature:: from_raw_const ( self , ( * self . raw ) . orig_signature ) }
133144 }
134145
146+ /// Returns signature of the committer of the original commit.
147+ ///
148+ /// The original commit is the one identified by [Self::orig_commit_id()].
149+ pub fn orig_committer ( & self ) -> Signature < ' _ > {
150+ unsafe { signature:: from_raw_const ( self , ( * self . raw ) . orig_committer ) }
151+ }
152+
135153 /// Returns line number where this hunk begins.
136154 ///
137155 /// Note that the start line is counting from 1.
@@ -162,6 +180,27 @@ impl<'blame> BlameHunk<'blame> {
162180 pub fn lines_in_hunk ( & self ) -> usize {
163181 unsafe { ( * self . raw ) . lines_in_hunk as usize }
164182 }
183+
184+ /// Get the short "summary" of the git commit message for the hunk.
185+ ///
186+ /// The returned message is the summary of the commit, comprising the first
187+ /// paragraph of the message with whitespace trimmed and squashed.
188+ ///
189+ /// `None` may be returned if an error occurs or if the summary is not valid
190+ /// utf-8.
191+ pub fn summary ( & self ) -> Option < & str > {
192+ self . summary_bytes ( ) . and_then ( |s| str:: from_utf8 ( s) . ok ( ) )
193+ }
194+
195+ /// Get the short "summary" of the git commit message for the hunk.
196+ ///
197+ /// The returned message is the summary of the commit, comprising the first
198+ /// paragraph of the message with whitespace trimmed and squashed.
199+ ///
200+ /// `None` may be returned if an error occurs
201+ pub fn summary_bytes ( & self ) -> Option < & [ u8 ] > {
202+ unsafe { crate :: opt_bytes ( self , ( * self . raw ) . summary ) }
203+ }
165204}
166205
167206impl Default for BlameOptions {
@@ -346,13 +385,23 @@ mod tests {
346385 File :: create ( & root. join ( "foo/bar" ) ) . unwrap ( ) ;
347386 index. add_path ( Path :: new ( "foo/bar" ) ) . unwrap ( ) ;
348387
388+ let committer_sig = crate :: Signature :: now ( "FizzBuzz" , "bar@example.com" )
389+ . expect ( "Signature creation should succeed" ) ;
390+
349391 let id = index. write_tree ( ) . unwrap ( ) ;
350392 let tree = repo. find_tree ( id) . unwrap ( ) ;
351393 let sig = repo. signature ( ) . unwrap ( ) ;
352394 let id = repo. refname_to_id ( "HEAD" ) . unwrap ( ) ;
353395 let parent = repo. find_commit ( id) . unwrap ( ) ;
354396 let commit = repo
355- . commit ( Some ( "HEAD" ) , & sig, & sig, "commit" , & tree, & [ & parent] )
397+ . commit (
398+ Some ( "HEAD" ) ,
399+ & sig,
400+ & committer_sig,
401+ "commit" ,
402+ & tree,
403+ & [ & parent] ,
404+ )
356405 . unwrap ( ) ;
357406
358407 let blame = repo. blame_file ( Path :: new ( "foo/bar" ) , None ) . unwrap ( ) ;
@@ -364,9 +413,16 @@ mod tests {
364413 assert_eq ! ( hunk. final_commit_id( ) , commit) ;
365414 assert_eq ! ( hunk. final_signature( ) . name( ) , sig. name( ) ) ;
366415 assert_eq ! ( hunk. final_signature( ) . email( ) , sig. email( ) ) ;
416+ assert_eq ! ( hunk. orig_signature( ) . name( ) , sig. name( ) ) ;
417+ assert_eq ! ( hunk. orig_signature( ) . email( ) , sig. email( ) ) ;
418+ assert_eq ! ( hunk. final_committer( ) . name( ) , committer_sig. name( ) ) ;
419+ assert_eq ! ( hunk. final_committer( ) . email( ) , committer_sig. email( ) ) ;
420+ assert_eq ! ( hunk. orig_committer( ) . name( ) , committer_sig. name( ) ) ;
421+ assert_eq ! ( hunk. orig_committer( ) . email( ) , committer_sig. email( ) ) ;
367422 assert_eq ! ( hunk. final_start_line( ) , 1 ) ;
368423 assert_eq ! ( hunk. path( ) , Some ( Path :: new( "foo/bar" ) ) ) ;
369424 assert_eq ! ( hunk. lines_in_hunk( ) , 0 ) ;
425+ assert_eq ! ( hunk. summary( ) , Some ( "commit" ) ) ;
370426 assert ! ( !hunk. is_boundary( ) ) ;
371427
372428 let blame_buffer = blame. blame_buffer ( "\n " . as_bytes ( ) ) . unwrap ( ) ;
0 commit comments