@@ -30,7 +30,7 @@ import {
30
30
} from '../../../../git/parsers/logParser' ;
31
31
import type { GitGraphSearch , GitGraphSearchResultData , GitGraphSearchResults } from '../../../../git/search' ;
32
32
import { getSearchQueryComparisonKey , parseSearchQueryCommand } from '../../../../git/search' ;
33
- import { getDefaultBranchName , isBranchStarred } from '../../../../git/utils/-webview/branch.utils' ;
33
+ import { getBranchMergeBaseAndCommonCommit , isBranchStarred } from '../../../../git/utils/-webview/branch.utils' ;
34
34
import { getRemoteIconUri } from '../../../../git/utils/-webview/icons' ;
35
35
import { groupWorktreesByBranch } from '../../../../git/utils/-webview/worktree.utils' ;
36
36
import {
@@ -349,7 +349,10 @@ export class GraphGitSubProvider implements GitGraphSubProvider {
349
349
branchId = branch ?. id ?? getBranchId ( repoPath , false , tip ) ;
350
350
351
351
// Check if branch has commits that can be recomposed and get merge base
352
- const mergeBase = await this . getMergeBase ( branch , repoPath ) ;
352
+ const mergeBaseResult =
353
+ branch && ( await getBranchMergeBaseAndCommonCommit ( this . container , branch ) ) ;
354
+ const isRecomposable = Boolean ( mergeBaseResult && mergeBaseResult . commit !== branch ?. sha ) ;
355
+ const mergeBase = isRecomposable ? mergeBaseResult : undefined ;
353
356
354
357
context = {
355
358
webviewItem : `gitlens:branch${ head ? '+current' : '' } ${
@@ -625,74 +628,6 @@ export class GraphGitSubProvider implements GitGraphSubProvider {
625
628
return getCommitsForGraphCore . call ( this , defaultLimit , selectSha , undefined , cancellation ) ;
626
629
}
627
630
628
- private async getMergeBase (
629
- branch : GitBranch | undefined ,
630
- repoPath : string ,
631
- ) : Promise < { commit : string ; branch : string ; remote : boolean } | undefined > {
632
- if ( ! branch || branch . remote ) return undefined ;
633
-
634
- try {
635
- const upstreamName = branch . upstream ?. name ;
636
- const svc = this . container . git . getRepositoryService ( repoPath ) ;
637
-
638
- // Get stored merge target configurations
639
- const [ targetBranchResult , mergeBaseResult , defaultBranchResult ] = await Promise . allSettled ( [
640
- svc . branches . getStoredMergeTargetBranchName ?.( branch . name ) ,
641
- svc . branches . getBaseBranchName ?.( branch . name ) ,
642
- getDefaultBranchName ( this . container , branch . repoPath , branch . name ) ,
643
- ] ) ;
644
- const targetBranch = getSettledValue ( targetBranchResult ) ;
645
- const validTargetBranch = targetBranch && targetBranch !== upstreamName ? targetBranch : undefined ;
646
- const mergeBase = getSettledValue ( mergeBaseResult ) || getSettledValue ( defaultBranchResult ) ;
647
- const validMergeBase = mergeBase && mergeBase !== upstreamName ? mergeBase : undefined ;
648
-
649
- // Select target with most recent common commit (closest to branch tip)
650
- const validTargets = [ validTargetBranch , validMergeBase ] ;
651
- const recentMergeBase = await this . selectMostRecentMergeBase ( branch . name , validTargets , svc ) ;
652
-
653
- const isRecomposable = Boolean ( recentMergeBase && recentMergeBase . commit !== branch . sha ) ;
654
- return isRecomposable ? recentMergeBase : undefined ;
655
- } catch {
656
- // If we can't determine, assume not recomposable
657
- return undefined ;
658
- }
659
- }
660
-
661
- private async selectMostRecentMergeBase (
662
- branchName : string ,
663
- targets : ( string | undefined ) [ ] ,
664
- svc : ReturnType < typeof this . container . git . getRepositoryService > ,
665
- ) : Promise < { commit : string ; branch : string ; remote : boolean } | undefined > {
666
- const isString = ( t : string | undefined ) : t is string => Boolean ( t ) ;
667
- const mergeBaseResults = await Promise . allSettled (
668
- targets . filter ( isString ) . map ( async target => {
669
- const commit = await svc . refs . getMergeBase ( branchName , target ) ;
670
- return {
671
- commit : commit ,
672
- branch : target ,
673
- } ;
674
- } ) ,
675
- ) ;
676
- const mergeBases = mergeBaseResults
677
- . map ( result => getSettledValue ( result ) )
678
- . filter ( ( r ) : r is { commit : string ; branch : string ; remote : boolean } => isString ( r ?. commit ) ) ;
679
-
680
- if ( mergeBases . length === 0 ) return undefined ;
681
-
682
- let mostRecentMergeBase = mergeBases [ 0 ] ;
683
- for ( let i = 1 ; i < mergeBases . length ; i ++ ) {
684
- const isCurrentMoreRecent = await svc . commits . isAncestorOf (
685
- mostRecentMergeBase ?. commit ,
686
- mergeBases [ i ] . commit ,
687
- ) ;
688
- if ( isCurrentMoreRecent ) {
689
- mostRecentMergeBase = mergeBases [ i ] ;
690
- }
691
- }
692
-
693
- return mostRecentMergeBase ;
694
- }
695
-
696
631
@log < GraphGitSubProvider [ 'searchGraph' ] > ( {
697
632
args : {
698
633
1 : s =>
0 commit comments