@@ -67,6 +67,10 @@ pub(crate) fn worktree(repo_path: &Path, json: bool, show_base: bool, show_files
67
67
// Print branches with commits and assigned files
68
68
if !stacks. is_empty ( ) {
69
69
print_branch_sections ( & stacks, & assignments_by_file, & changes, & project, show_files, ctx) ?;
70
+
71
+ // Print legend for commit status decorations
72
+ println ! ( "Legend: {} Remote-only {} Pushed {} Local-only" ,
73
+ "R" . red( ) , "P" . yellow( ) , "L" . green( ) ) ;
70
74
}
71
75
72
76
// Print unassigned files
@@ -298,9 +302,19 @@ fn print_branch_sections(
298
302
let commit_short = & commit. id . to_string ( ) [ ..7 ] ;
299
303
let commit_id = CliId :: commit ( commit. id ) . to_string ( ) . underline ( ) . blue ( ) ;
300
304
let message_line = format_commit_message ( & commit. message ) ;
305
+
306
+ // Check if this upstream commit also exists in local commits (pushed)
307
+ let is_also_local = branch. commits . iter ( ) . any ( |local| local. id == commit. id ) ;
308
+ let status_decoration = if is_also_local {
309
+ "P" . yellow ( ) // Pushed (exists both upstream and locally)
310
+ } else {
311
+ "R" . red ( ) // Remote-only (upstream only)
312
+ } ;
313
+
301
314
println ! (
302
- "{}● {} {} {}" ,
315
+ "{}● {} {} {} {}" ,
303
316
prefix,
317
+ status_decoration,
304
318
commit_id,
305
319
commit_short. blue( ) ,
306
320
message_line
@@ -330,14 +344,25 @@ fn print_branch_sections(
330
344
}
331
345
}
332
346
333
- // Show local commits
347
+ // Show local commits (but skip ones already shown as upstream)
334
348
for commit in & branch. commits {
349
+ // Skip if this commit was already shown in upstream commits
350
+ let already_shown = branch. upstream_commits . iter ( ) . any ( |upstream| upstream. id == commit. id ) ;
351
+ if already_shown {
352
+ continue ;
353
+ }
354
+
335
355
let commit_short = & commit. id . to_string ( ) [ ..7 ] ;
336
356
let commit_id = CliId :: commit ( commit. id ) . to_string ( ) . underline ( ) . blue ( ) ;
337
357
let message_line = format_commit_message ( & commit. message ) ;
358
+
359
+ // Local-only commits (not pushed)
360
+ let status_decoration = "L" . green ( ) ;
361
+
338
362
println ! (
339
- "{}● {} {} {}" ,
363
+ "{}● {} {} {} {}" ,
340
364
prefix,
365
+ status_decoration,
341
366
commit_id,
342
367
commit_short. blue( ) ,
343
368
message_line
0 commit comments