@@ -1945,16 +1945,24 @@ impl MonoApiService {
19451945 . ok_or_else ( || GitError :: CustomError ( format ! ( "Commit not found: {}" , cl. to_hash) ) ) ?;
19461946 let commit: Commit = Commit :: from_mega_model ( commit_model) ;
19471947
1948- if cl. path != "/" {
1949- let path = PathBuf :: from ( cl. path . clone ( ) ) ;
1950- // because only parent tree is needed so we skip current directory
1951- let update_chain = self . search_tree_for_update ( path. parent ( ) . unwrap ( ) ) . await ?;
1952- let result =
1953- MonoServiceLogic :: build_result_by_chain ( path, update_chain, commit. tree_id ) ?;
1954- self . apply_update_result ( & result, "cl merge generated commit" , Some ( cl. link . as_str ( ) ) )
1955- . await ?;
1948+ let normalized_path = MonoServiceLogic :: clean_path_str ( & cl. path ) ;
1949+ let ( path, update_chain) = if normalized_path == "/" {
1950+ ( PathBuf :: from ( "/" ) , Vec :: new ( ) )
1951+ } else {
1952+ let path = PathBuf :: from ( & normalized_path) ;
1953+ let parent = path. parent ( ) . ok_or_else ( || {
1954+ GitError :: CustomError ( format ! ( "Invalid CL path: {}" , normalized_path) )
1955+ } ) ?;
1956+ let update_chain = self . search_tree_for_update ( parent) . await ?;
1957+ ( path, update_chain)
1958+ } ;
1959+ let result = MonoServiceLogic :: build_result_by_chain ( path, update_chain, commit. tree_id ) ?;
1960+ self . apply_update_result ( & result, "cl merge generated commit" , Some ( cl. link . as_str ( ) ) )
1961+ . await ?;
1962+
1963+ if normalized_path != "/" {
19561964 storage
1957- . remove_none_cl_refs ( & cl . path )
1965+ . remove_none_cl_refs ( & normalized_path )
19581966 . await
19591967 . map_err ( |e| GitError :: CustomError ( format ! ( "Failed to remove refs: {}" , e) ) ) ?;
19601968 // TODO: self.clean_dangling_commits().await;
@@ -3334,6 +3342,68 @@ mod test {
33343342 assert_eq ! ( updates[ 0 ] . commit_id, new_commit_id) ;
33353343 }
33363344
3345+ #[ tokio:: test]
3346+ async fn test_root_merge_flow_updates_cl_ref_and_main ( ) {
3347+ let merged_tree_id =
3348+ ObjectHash :: from_str ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ) . unwrap ( ) ;
3349+ let root_result =
3350+ MonoServiceLogic :: build_result_by_chain ( PathBuf :: from ( "/" ) , vec ! [ ] , merged_tree_id)
3351+ . expect ( "root path should build a valid update result" ) ;
3352+
3353+ assert_eq ! ( root_result. ref_updates. len( ) , 1 ) ;
3354+ assert_eq ! ( root_result. ref_updates[ 0 ] . path, "/" ) ;
3355+
3356+ let refs = vec ! [
3357+ mega_refs:: Model {
3358+ id: 1 ,
3359+ path: "/" . to_string( ) ,
3360+ ref_name: "refs/cl/abcd1234" . to_string( ) ,
3361+ ref_commit_hash: "1111111111111111111111111111111111111111" . to_string( ) ,
3362+ ref_tree_hash: "2222222222222222222222222222222222222222" . to_string( ) ,
3363+ created_at: chrono:: Utc :: now( ) . naive_utc( ) ,
3364+ updated_at: chrono:: Utc :: now( ) . naive_utc( ) ,
3365+ is_cl: true ,
3366+ } ,
3367+ mega_refs:: Model {
3368+ id: 2 ,
3369+ path: "/" . to_string( ) ,
3370+ ref_name: MEGA_BRANCH_NAME . to_string( ) ,
3371+ ref_commit_hash: "3333333333333333333333333333333333333333" . to_string( ) ,
3372+ ref_tree_hash: "4444444444444444444444444444444444444444" . to_string( ) ,
3373+ created_at: chrono:: Utc :: now( ) . naive_utc( ) ,
3374+ updated_at: chrono:: Utc :: now( ) . naive_utc( ) ,
3375+ is_cl: false ,
3376+ } ,
3377+ ] ;
3378+
3379+ let mut commits = Vec :: new ( ) ;
3380+ let mut updates = Vec :: new ( ) ;
3381+ let mut new_commit_id = String :: new ( ) ;
3382+
3383+ MonoServiceLogic :: process_ref_updates (
3384+ & root_result,
3385+ & refs,
3386+ "merge root cl" ,
3387+ & mut commits,
3388+ & mut updates,
3389+ & mut new_commit_id,
3390+ )
3391+ . expect ( "root merge flow should produce ref updates" ) ;
3392+
3393+ assert_eq ! ( commits. len( ) , 1 ) ;
3394+ assert_eq ! ( updates. len( ) , 2 ) ;
3395+ assert ! ( !new_commit_id. is_empty( ) ) ;
3396+
3397+ assert_eq ! ( updates[ 0 ] . ref_name, "refs/cl/abcd1234" ) ;
3398+ assert_eq ! ( updates[ 1 ] . ref_name, MEGA_BRANCH_NAME ) ;
3399+ assert ! ( updates. iter( ) . all( |u| u. path == "/" ) ) ;
3400+ assert ! (
3401+ updates
3402+ . iter( )
3403+ . all( |u| u. tree_hash == merged_tree_id. to_string( ) )
3404+ ) ;
3405+ }
3406+
33373407 #[ test]
33383408 fn test_map_tree_items_to_commits ( ) {
33393409 let id1 = ObjectHash :: Sha1 ( [ 1u8 ; 20 ] ) ;
0 commit comments