11use anyhow:: { Result , bail} ;
22use but_ctx:: Context ;
3- use but_oxidize:: { ObjectIdExt , OidExt } ;
3+ use but_oxidize:: { ObjectIdExt as _ , OidExt } ;
44use gitbutler_project:: Project ;
5+ use gix:: prelude:: ObjectIdExt ;
56
67use crate :: { legacy:: id:: CliId , tui, utils:: OutputChannel } ;
78
89pub ( crate ) fn describe_target (
910 project : & Project ,
1011 out : & mut OutputChannel ,
1112 target : & str ,
13+ message : Option < & str > ,
1214) -> Result < ( ) > {
1315 let mut ctx = Context :: new_from_legacy_project ( project. clone ( ) ) ?;
1416
@@ -31,10 +33,10 @@ pub(crate) fn describe_target(
3133
3234 match cli_id {
3335 CliId :: Branch { name, .. } => {
34- edit_branch_name ( & ctx, project, name, out) ?;
36+ edit_branch_name ( & ctx, project, name, out, message ) ?;
3537 }
3638 CliId :: Commit { oid } => {
37- edit_commit_message_by_id ( & ctx, project, * oid, out) ?;
39+ edit_commit_message_by_id ( & ctx, project, * oid, out, message ) ?;
3840 }
3941 _ => {
4042 bail ! ( "Target must be a commit ID, not {}" , cli_id. kind( ) ) ;
@@ -49,6 +51,7 @@ fn edit_branch_name(
4951 project : & Project ,
5052 branch_name : & str ,
5153 out : & mut OutputChannel ,
54+ message : Option < & str > ,
5255) -> Result < ( ) > {
5356 // Find which stack this branch belongs to
5457 let stacks = but_api:: legacy:: workspace:: stacks (
@@ -62,7 +65,8 @@ fn edit_branch_name(
6265 }
6366
6467 if let Some ( sid) = stack_entry. id {
65- let new_name = get_branch_name_from_editor ( branch_name) ?;
68+ let new_name = prepare_provided_message ( message, "branch name" )
69+ . unwrap_or_else ( || get_branch_name_from_editor ( branch_name) ) ?;
6670 but_api:: legacy:: stack:: update_branch_name (
6771 project. id ,
6872 sid,
@@ -79,11 +83,22 @@ fn edit_branch_name(
7983 bail ! ( "Branch '{}' not found in any stack" , branch_name)
8084}
8185
86+ fn prepare_provided_message ( msg : Option < & str > , entity : & str ) -> Option < Result < String > > {
87+ msg. map ( |msg| {
88+ let trimmed = msg. trim ( ) ;
89+ if trimmed. is_empty ( ) {
90+ bail ! ( "Aborting due to empty {entity}" ) ;
91+ }
92+ Ok ( trimmed. to_string ( ) )
93+ } )
94+ }
95+
8296fn edit_commit_message_by_id (
8397 ctx : & Context ,
8498 project : & Project ,
8599 commit_oid : gix:: ObjectId ,
86100 out : & mut OutputChannel ,
101+ message : Option < & str > ,
87102) -> Result < ( ) > {
88103 // Find which stack this commit belongs to
89104 let stacks = but_api:: legacy:: workspace:: stacks ( project. id , None ) ?;
@@ -132,18 +147,23 @@ fn edit_commit_message_by_id(
132147 let stack_id = stack_id
133148 . ok_or_else ( || anyhow:: anyhow!( "Could not find stack for commit {}" , commit_oid) ) ?;
134149
135- // Get the files changed in this commit using but_api
136- let commit_details = but_api:: legacy:: diff:: commit_details ( project. id , commit_oid. into ( ) ) ?;
137- let changed_files = get_changed_files_from_commit_details ( & commit_details) ;
138-
139150 // Get current commit message
140151 let current_message = commit_message. to_string ( ) ;
141152
142- // Open editor with current message and file list
143- let new_message = get_commit_message_from_editor ( & current_message, & changed_files) ?;
153+ // Get new message from provided argument or editor
154+ let new_message = prepare_provided_message ( message, "commit message" ) . unwrap_or_else ( || {
155+ let commit_details = but_api:: legacy:: diff:: commit_details ( project. id , commit_oid. into ( ) ) ?;
156+ let changed_files = get_changed_files_from_commit_details ( & commit_details) ;
157+
158+ // Open editor with current message and file list
159+ get_commit_message_from_editor ( & current_message, & changed_files)
160+ } ) ?;
144161
145162 if new_message. trim ( ) == current_message. trim ( ) {
146- bail ! ( "No changes to commit message." ) ;
163+ if let Some ( out) = out. for_human ( ) {
164+ writeln ! ( out, "No changes to commit message - nothing to be done" ) ?;
165+ }
166+ return Ok ( ( ) ) ;
147167 }
148168
149169 // Use gitbutler_branch_actions::update_commit_message instead of low-level primitives
@@ -156,11 +176,12 @@ fn edit_commit_message_by_id(
156176 ) ?;
157177
158178 if let Some ( out) = out. for_human ( ) {
179+ let repo = ctx. repo . get ( ) ?;
159180 writeln ! (
160181 out,
161182 "Updated commit message for {} (now {})" ,
162- commit_oid. to_hex_with_len ( 7 ) ,
163- new_commit_oid. to_gix( ) . to_hex_with_len ( 7 )
183+ commit_oid. attach ( & repo ) . shorten_or_id ( ) ,
184+ new_commit_oid. to_gix( ) . attach ( & repo ) . shorten_or_id ( )
164185 ) ?;
165186 }
166187
@@ -236,3 +257,33 @@ fn get_branch_name_from_editor(current_name: &str) -> Result<String> {
236257
237258 Ok ( branch_name)
238259}
260+
261+ #[ cfg( test) ]
262+ mod tests {
263+
264+ mod prepare_provided_message {
265+ use super :: super :: * ;
266+
267+ #[ test]
268+ fn empty_is_fails ( ) {
269+ assert_eq ! (
270+ prepare_provided_message( Some ( "" ) , "message" )
271+ . unwrap( )
272+ . unwrap_err( )
273+ . to_string( ) ,
274+ "Aborting due to empty message"
275+ ) ;
276+ }
277+
278+ #[ test]
279+ fn empty_is_after_trimming_fails ( ) {
280+ assert_eq ! (
281+ prepare_provided_message( Some ( " " ) , "message" )
282+ . unwrap( )
283+ . unwrap_err( )
284+ . to_string( ) ,
285+ "Aborting due to empty message"
286+ ) ;
287+ }
288+ }
289+ }
0 commit comments