@@ -518,6 +518,31 @@ fn selection_marker() -> &'static str {
518518 }
519519}
520520
521+ /// Check if a branch subtree contains the target branch or a display_author PR
522+ /// Returns (has_target_branch, has_display_author_pr)
523+ fn subtree_contains (
524+ branch : & Branch ,
525+ target_branch : & str ,
526+ display_authors : & [ String ] ,
527+ pr_cache : Option < & std:: collections:: HashMap < String , github:: PullRequest > > ,
528+ ) -> ( bool , bool ) {
529+ // Check this branch
530+ let is_target = branch. name == target_branch;
531+ let has_author = pr_cache
532+ . and_then ( |cache| cache. get ( & branch. name ) )
533+ . map ( |pr| display_authors. contains ( & pr. user . login ) )
534+ . unwrap_or ( false ) ;
535+
536+ // Recursively check children
537+ let ( child_has_target, child_has_author) = branch
538+ . branches
539+ . iter ( )
540+ . map ( |b| subtree_contains ( b, target_branch, display_authors, pr_cache) )
541+ . fold ( ( false , false ) , |( t1, a1) , ( t2, a2) | ( t1 || t2, a1 || a2) ) ;
542+
543+ ( is_target || child_has_target, has_author || child_has_author)
544+ }
545+
521546#[ allow( clippy:: too_many_arguments) ]
522547fn recur_tree (
523548 git_repo : & GitRepo ,
@@ -856,32 +881,44 @@ fn recur_tree(
856881 }
857882
858883 let mut branches_sorted = branch. branches . iter ( ) . collect :: < Vec < _ > > ( ) ;
859- // Pre-compute is_ancestor results to avoid repeated git merge-base calls during sorting
860- let ancestor_cache: std:: collections:: HashMap < & str , bool > = branches_sorted
884+
885+ // Pre-compute subtree properties for sorting
886+ let subtree_cache: std:: collections:: HashMap < & str , ( bool , bool ) > = branches_sorted
861887 . iter ( )
862888 . map ( |b| {
863889 (
864890 b. name . as_str ( ) ,
865- git_repo . is_ancestor ( & b . name , orig_branch) . unwrap_or ( false ) ,
891+ subtree_contains ( b , orig_branch, display_authors , pr_cache ) ,
866892 )
867893 } )
868894 . collect ( ) ;
895+
869896 branches_sorted. sort_by ( |& a, & b| {
870- let a_is_ancestor = ancestor_cache
897+ let ( a_has_current , a_has_author ) = subtree_cache
871898 . get ( a. name . as_str ( ) )
872899 . copied ( )
873- . unwrap_or ( false ) ;
874- let b_is_ancestor = ancestor_cache
900+ . unwrap_or ( ( false , false ) ) ;
901+ let ( b_has_current , b_has_author ) = subtree_cache
875902 . get ( b. name . as_str ( ) )
876903 . copied ( )
877- . unwrap_or ( false ) ;
878- match ( a_is_ancestor, b_is_ancestor) {
879- ( true , true ) => a. name . cmp ( & b. name ) ,
880- ( true , false ) => std:: cmp:: Ordering :: Less ,
881- ( false , true ) => std:: cmp:: Ordering :: Greater ,
882- ( false , false ) => a. name . cmp ( & b. name ) ,
904+ . unwrap_or ( ( false , false ) ) ;
905+
906+ // Priority 1: subtree contains current branch
907+ match ( a_has_current, b_has_current) {
908+ ( true , false ) => return std:: cmp:: Ordering :: Less ,
909+ ( false , true ) => return std:: cmp:: Ordering :: Greater ,
910+ _ => { }
911+ }
912+ // Priority 2: subtree contains display_author PR
913+ match ( a_has_author, b_has_author) {
914+ ( true , false ) => return std:: cmp:: Ordering :: Less ,
915+ ( false , true ) => return std:: cmp:: Ordering :: Greater ,
916+ _ => { }
883917 }
918+ // Priority 3: alphabetical
919+ a. name . cmp ( & b. name )
884920 } ) ;
921+
885922 for child in branches_sorted {
886923 recur_tree (
887924 git_repo,
0 commit comments