@@ -4,6 +4,7 @@ use but_core::ui::{TreeChange, TreeStatus};
4
4
use but_hunk_assignment:: HunkAssignment ;
5
5
use but_settings:: AppSettings ;
6
6
use but_workspace:: ui:: StackDetails ;
7
+ use chrono:: { DateTime , TimeZone , Utc } ;
7
8
use colored:: { ColoredString , Colorize } ;
8
9
use gitbutler_command_context:: CommandContext ;
9
10
use gitbutler_commit:: commit_ext:: CommitExt ;
@@ -32,7 +33,12 @@ struct WorktreeStatus {
32
33
common_merge_base : CommonMergeBase ,
33
34
}
34
35
35
- pub ( crate ) fn worktree ( repo_path : & Path , json : bool , show_files : bool ) -> anyhow:: Result < ( ) > {
36
+ pub ( crate ) fn worktree (
37
+ repo_path : & Path ,
38
+ json : bool ,
39
+ show_files : bool ,
40
+ verbose : bool ,
41
+ ) -> anyhow:: Result < ( ) > {
36
42
let project = Project :: find_by_path ( repo_path) . expect ( "Failed to create project from path" ) ;
37
43
let ctx = & mut CommandContext :: open ( & project, AppSettings :: load_from_default_path_creating ( ) ?) ?;
38
44
but_rules:: process_rules ( ctx) . ok ( ) ; // TODO: this is doing double work (dependencies can be reused)
@@ -108,6 +114,7 @@ pub(crate) fn worktree(repo_path: &Path, json: bool, show_files: bool) -> anyhow
108
114
assignments,
109
115
& worktree_changes. worktree_changes . changes ,
110
116
show_files,
117
+ verbose,
111
118
& mut stack_mark,
112
119
ctx,
113
120
) ?;
@@ -161,12 +168,14 @@ fn print_assignments(assignments: &Vec<FileAssignment>, changes: &[TreeChange])
161
168
}
162
169
}
163
170
171
+ #[ expect( clippy:: too_many_arguments) ]
164
172
pub fn print_group (
165
173
project : & Project ,
166
174
group : Option < StackDetails > ,
167
175
assignments : Vec < FileAssignment > ,
168
176
changes : & [ TreeChange ] ,
169
177
show_files : bool ,
178
+ verbose : bool ,
170
179
stack_mark : & mut Option < ColoredString > ,
171
180
ctx : & mut CommandContext ,
172
181
) -> anyhow:: Result < ( ) > {
@@ -206,20 +215,49 @@ pub fn print_group(
206
215
} else {
207
216
"" . normal ( )
208
217
} ;
209
- println ! (
210
- "● {}{} {} {} {}" ,
211
- & commit. id. to_string( ) [ ..2 ] . blue( ) . underline( ) ,
212
- & commit. id. to_string( ) [ 2 ..7 ] . blue( ) ,
213
- conflicted_str,
214
- commit
215
- . message
216
- . to_string( )
217
- . replace( '\n' , " " )
218
- . chars( )
219
- . take( 50 )
220
- . collect:: <String >( ) ,
221
- mark. unwrap_or_default( )
222
- ) ;
218
+
219
+ if verbose {
220
+ // Verbose format: author and timestamp on first line, message on second line
221
+ let datetime = DateTime :: from_timestamp_millis ( commit. created_at as i64 )
222
+ . unwrap_or_else ( || Utc . timestamp_millis_opt ( 0 ) . unwrap ( ) ) ;
223
+ let formatted_time = datetime. format ( "%Y-%m-%d %H:%M:%S" ) ;
224
+
225
+ println ! (
226
+ "● {}{} {} {} {} {}" ,
227
+ & commit. id. to_string( ) [ ..2 ] . blue( ) . underline( ) ,
228
+ & commit. id. to_string( ) [ 2 ..7 ] . blue( ) ,
229
+ conflicted_str,
230
+ commit. author. name. dimmed( ) ,
231
+ formatted_time. to_string( ) . dimmed( ) ,
232
+ mark. unwrap_or_default( )
233
+ ) ;
234
+ println ! (
235
+ "│ {}" ,
236
+ commit
237
+ . message
238
+ . to_string( )
239
+ . replace( '\n' , " " )
240
+ . chars( )
241
+ . take( 100 )
242
+ . collect:: <String >( )
243
+ ) ;
244
+ } else {
245
+ // Original format: everything on one line
246
+ println ! (
247
+ "● {}{} {} {} {}" ,
248
+ & commit. id. to_string( ) [ ..2 ] . blue( ) . underline( ) ,
249
+ & commit. id. to_string( ) [ 2 ..7 ] . blue( ) ,
250
+ conflicted_str,
251
+ commit
252
+ . message
253
+ . to_string( )
254
+ . replace( '\n' , " " )
255
+ . chars( )
256
+ . take( 50 )
257
+ . collect:: <String >( ) ,
258
+ mark. unwrap_or_default( )
259
+ ) ;
260
+ }
223
261
if show_files {
224
262
let commit_details =
225
263
but_api:: diff:: commit_details ( project. id , commit. id . into ( ) ) ?;
0 commit comments