11use std:: fmt:: Display ;
22
33use super :: RepoPath ;
4- use crate :: {
5- error:: Result ,
6- sync:: { commit_details:: get_author_of_commit, repository:: repo} ,
7- } ;
8- use git2:: { Commit , Error , Oid } ;
4+ use crate :: { error:: Result , sync:: repository:: repo} ;
5+ use git2:: Oid ;
96use scopetime:: scope_time;
107use unicode_truncate:: UnicodeTruncateStr ;
118
@@ -93,6 +90,12 @@ impl From<gix::ObjectId> for CommitId {
9390 }
9491}
9592
93+ impl From < CommitId > for gix:: ObjectId {
94+ fn from ( id : CommitId ) -> Self {
95+ Self :: from_bytes_or_panic ( id. 0 . as_bytes ( ) )
96+ }
97+ }
98+
9699///
97100#[ derive( Debug , Clone ) ]
98101pub struct CommitInfo {
@@ -114,34 +117,36 @@ pub fn get_commits_info(
114117) -> Result < Vec < CommitInfo > > {
115118 scope_time ! ( "get_commits_info" ) ;
116119
117- let repo = repo ( repo_path) ?;
118- let mailmap = repo. mailmap ( ) ?;
119-
120- let commits = ids
121- . iter ( )
122- . map ( |id| repo. find_commit ( ( * id) . into ( ) ) )
123- . collect :: < std:: result:: Result < Vec < Commit > , Error > > ( ) ?
124- . into_iter ( ) ;
125-
126- let res = commits
127- . map ( |c : Commit | {
128- let message = get_message ( & c, Some ( message_length_limit) ) ;
129- let author = get_author_of_commit ( & c, & mailmap)
130- . name ( )
131- . map_or_else (
132- || String :: from ( "<unknown>" ) ,
133- String :: from,
134- ) ;
135- CommitInfo {
120+ let repo: gix:: Repository =
121+ gix:: ThreadSafeRepository :: discover_with_environment_overrides ( repo_path. gitpath ( ) )
122+ . map ( Into :: into) ?;
123+ let mailmap = repo. open_mailmap ( ) ;
124+
125+ ids. iter ( )
126+ . map ( |id| -> Result < _ > {
127+ let commit = repo. find_commit ( * id) ?;
128+ let commit_ref = commit. decode ( ) ?;
129+
130+ let message = gix_get_message (
131+ & commit_ref,
132+ Some ( message_length_limit) ,
133+ ) ;
134+
135+ let author = commit_ref. author ( ) ;
136+
137+ let author = mailmap. try_resolve ( author) . map_or_else (
138+ || author. name . into ( ) ,
139+ |signature| signature. name ,
140+ ) ;
141+
142+ Ok ( CommitInfo {
136143 message,
137- author,
138- time : c . time ( ) . seconds ( ) ,
139- id : CommitId ( c . id ( ) ) ,
140- }
144+ author : author . to_string ( ) ,
145+ time : commit_ref . time ( ) . seconds ,
146+ id : * id ,
147+ } )
141148 } )
142- . collect :: < Vec < _ > > ( ) ;
143-
144- Ok ( res)
149+ . collect ( )
145150}
146151
147152///
@@ -151,24 +156,35 @@ pub fn get_commit_info(
151156) -> Result < CommitInfo > {
152157 scope_time ! ( "get_commit_info" ) ;
153158
154- let repo = repo ( repo_path) ?;
155- let mailmap = repo. mailmap ( ) ?;
159+ let repo: gix:: Repository =
160+ gix:: ThreadSafeRepository :: discover_with_environment_overrides ( repo_path. gitpath ( ) )
161+ . map ( Into :: into) ?;
162+ let mailmap = repo. open_mailmap ( ) ;
163+
164+ let commit = repo. find_commit ( * commit_id) ?;
165+ let commit_ref = commit. decode ( ) ?;
166+
167+ let message = gix_get_message ( & commit_ref, None ) ;
156168
157- let commit = repo. find_commit ( ( * commit_id) . into ( ) ) ?;
158- let author = get_author_of_commit ( & commit, & mailmap) ;
169+ let author = commit_ref. author ( ) ;
170+
171+ let author = mailmap. try_resolve ( author) . map_or_else (
172+ || author. name . into ( ) ,
173+ |signature| signature. name ,
174+ ) ;
159175
160176 Ok ( CommitInfo {
161- message : commit . message ( ) . unwrap_or ( "" ) . into ( ) ,
162- author : author. name ( ) . unwrap_or ( "<unknown>" ) . into ( ) ,
163- time : commit . time ( ) . seconds ( ) ,
164- id : CommitId ( commit. id ( ) ) ,
177+ message,
178+ author : author. to_string ( ) ,
179+ time : commit_ref . time ( ) . seconds ,
180+ id : commit. id ( ) . detach ( ) . into ( ) ,
165181 } )
166182}
167183
168184/// if `message_limit` is set the message will be
169185/// limited to the first line and truncated to fit
170186pub fn get_message (
171- c : & Commit ,
187+ c : & git2 :: Commit ,
172188 message_limit : Option < usize > ,
173189) -> String {
174190 let msg = String :: from_utf8_lossy ( c. message_bytes ( ) ) ;
@@ -183,6 +199,24 @@ pub fn get_message(
183199 )
184200}
185201
202+ /// if `message_limit` is set the message will be
203+ /// limited to the first line and truncated to fit
204+ pub fn gix_get_message (
205+ commit_ref : & gix:: objs:: CommitRef ,
206+ message_limit : Option < usize > ,
207+ ) -> String {
208+ let message = commit_ref. message . to_string ( ) ;
209+ let message = message. trim ( ) ;
210+
211+ message_limit. map_or_else (
212+ || message. to_string ( ) ,
213+ |limit| {
214+ let message = message. lines ( ) . next ( ) . unwrap_or_default ( ) ;
215+ message. unicode_truncate ( limit) . 0 . to_string ( )
216+ } ,
217+ )
218+ }
219+
186220#[ cfg( test) ]
187221mod tests {
188222 use super :: get_commits_info;
0 commit comments