@@ -97,11 +97,10 @@ import type {
9797 GitGraphRowTag ,
9898} from '../../../git/models/graph' ;
9999import type { GitLog } from '../../../git/models/log' ;
100- import type { GitMergeStatus } from '../../../git/models/merge' ;
101100import type { MergeConflict } from '../../../git/models/mergeConflict' ;
102- import type { GitRebaseStatus } from '../../../git/models/rebase ' ;
103- import type { GitBranchReference , GitReference , GitTagReference } from '../../../git/models/reference' ;
104- import { createReference , getReferenceFromBranch , isBranchReference } from '../../../git/models/reference.utils' ;
101+ import type { GitPausedOperationStatus } from '../../../git/models/pausedOperationStatus ' ;
102+ import type { GitBranchReference , GitReference } from '../../../git/models/reference' ;
103+ import { createReference , isBranchReference } from '../../../git/models/reference.utils' ;
105104import type { GitReflog } from '../../../git/models/reflog' ;
106105import type { GitRemote } from '../../../git/models/remote' ;
107106import { getVisibilityCacheKey , sortRemotes } from '../../../git/models/remote' ;
@@ -236,6 +235,7 @@ import {
236235} from './git' ;
237236import type { GitLocation } from './locator' ;
238237import { findGitPath , InvalidGitConfigError , UnableToFindGitError } from './locator' ;
238+ import { abortPausedOperation , continuePausedOperation , getPausedOperationStatus } from './operations/pausedOperations' ;
239239import { CancelledRunError , fsExists , RunError } from './shell' ;
240240
241241const emptyArray = Object . freeze ( [ ] ) as unknown as any [ ] ;
@@ -299,8 +299,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
299299 private readonly _branchCache = new Map < string , Promise < GitBranch | undefined > > ( ) ;
300300 private readonly _branchesCache = new Map < string , Promise < PagedResult < GitBranch > > > ( ) ;
301301 private readonly _contributorsCache = new Map < string , Map < string , Promise < GitContributor [ ] > > > ( ) ;
302- private readonly _mergeStatusCache = new Map < string , Promise < GitMergeStatus | undefined > > ( ) ;
303- private readonly _rebaseStatusCache = new Map < string , Promise < GitRebaseStatus | undefined > > ( ) ;
302+ private readonly _pausedOperationStatusCache = new Map < string , Promise < GitPausedOperationStatus | undefined > > ( ) ;
304303 private readonly _remotesCache = new Map < string , Promise < GitRemote [ ] > > ( ) ;
305304 private readonly _repoInfoCache = new Map < string , RepositoryInfo > ( ) ;
306305 private readonly _stashesCache = new Map < string , GitStash | null > ( ) ;
@@ -356,14 +355,17 @@ export class LocalGitProvider implements GitProvider, Disposable {
356355 this . _trackedPaths . clear ( ) ;
357356 }
358357
359- if ( e . changed ( RepositoryChange . Merge , RepositoryChangeComparisonMode . Any ) ) {
360- this . _branchCache . delete ( repo . path ) ;
361- this . _mergeStatusCache . delete ( repo . path ) ;
362- }
363-
364- if ( e . changed ( RepositoryChange . Rebase , RepositoryChangeComparisonMode . Any ) ) {
358+ if (
359+ e . changed (
360+ RepositoryChange . CherryPick ,
361+ RepositoryChange . Merge ,
362+ RepositoryChange . Rebase ,
363+ RepositoryChange . Revert ,
364+ RepositoryChangeComparisonMode . Any ,
365+ )
366+ ) {
365367 this . _branchCache . delete ( repo . path ) ;
366- this . _rebaseStatusCache . delete ( repo . path ) ;
368+ this . _pausedOperationStatusCache . delete ( repo . path ) ;
367369 }
368370
369371 if ( e . changed ( RepositoryChange . Stash , RepositoryChangeComparisonMode . Any ) ) {
@@ -1479,7 +1481,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
14791481 }
14801482
14811483 if ( ! caches . length || caches . includes ( 'status' ) ) {
1482- cachesToClear . push ( this . _mergeStatusCache , this . _rebaseStatusCache ) ;
1484+ cachesToClear . push ( this . _pausedOperationStatusCache ) ;
14831485 }
14841486
14851487 if ( ! caches . length || caches . includes ( 'tags' ) ) {
@@ -1872,7 +1874,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
18721874
18731875 // Trap and cache expected blame errors
18741876 if ( document . state != null ) {
1875- const msg = ex ?. toString ( ) ?? '' ;
1877+ const msg : string = ex ?. toString ( ) ?? '' ;
18761878 Logger . debug ( scope , `Cache replace (with empty promise): '${ key } '; reason=${ msg } ` ) ;
18771879
18781880 const value : CachedBlame = {
@@ -1968,7 +1970,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
19681970
19691971 // Trap and cache expected blame errors
19701972 if ( document . state != null ) {
1971- const msg = ex ?. toString ( ) ?? '' ;
1973+ const msg : string = ex ?. toString ( ) ?? '' ;
19721974 Logger . debug ( scope , `Cache replace (with empty promise): '${ key } '; reason=${ msg } ` ) ;
19731975
19741976 const value : CachedBlame = {
@@ -2220,13 +2222,14 @@ export class LocalGitProvider implements GitProvider, Disposable {
22202222
22212223 const [ name , upstream ] = data [ 0 ] . split ( '\n' ) ;
22222224
2223- const [ rebaseStatusResult , committerDateResult ] = await Promise . allSettled ( [
2224- isDetachedHead ( name ) ? this . getRebaseStatus ( repoPath ) : undefined ,
2225+ const [ pausedOpStatusResult , committerDateResult ] = await Promise . allSettled ( [
2226+ isDetachedHead ( name ) ? this . getPausedOperationStatus ( repoPath ) : undefined ,
22252227 this . git . log__recent_committerdate ( repoPath , commitOrdering ) ,
22262228 ] ) ;
22272229
22282230 const committerDate = getSettledValue ( committerDateResult ) ;
2229- const rebaseStatus = getSettledValue ( rebaseStatusResult ) ;
2231+ const pausedOpStatus = getSettledValue ( pausedOpStatusResult ) ;
2232+ const rebaseStatus = pausedOpStatus ?. type === 'rebase' ? pausedOpStatus : undefined ;
22302233
22312234 return new GitBranch (
22322235 this . container ,
@@ -3539,7 +3542,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
35393542 } catch ( ex ) {
35403543 // Trap and cache expected diff errors
35413544 if ( document . state != null ) {
3542- const msg = ex ?. toString ( ) ?? '' ;
3545+ const msg : string = ex ?. toString ( ) ?? '' ;
35433546 Logger . debug ( scope , `Cache replace (with empty promise): '${ key } '` ) ;
35443547
35453548 const value : CachedDiff = {
@@ -3624,7 +3627,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
36243627 } catch ( ex ) {
36253628 // Trap and cache expected diff errors
36263629 if ( document . state != null ) {
3627- const msg = ex ?. toString ( ) ?? '' ;
3630+ const msg : string = ex ?. toString ( ) ?? '' ;
36283631 Logger . debug ( scope , `Cache replace (with empty promise): '${ key } '` ) ;
36293632
36303633 const value : CachedDiff = {
@@ -4417,170 +4420,24 @@ export class LocalGitProvider implements GitProvider, Disposable {
44174420 }
44184421 }
44194422
4423+ @gate ( )
44204424 @log ( )
4421- async getMergeStatus ( repoPath : string ) : Promise < GitMergeStatus | undefined > {
4422- let status = this . useCaching ? this . _mergeStatusCache . get ( repoPath ) : undefined ;
4423- if ( status == null ) {
4424- async function getCore ( this : LocalGitProvider ) : Promise < GitMergeStatus | undefined > {
4425- const merge = await this . git . rev_parse__verify ( repoPath , 'MERGE_HEAD' ) ;
4426- if ( merge == null ) return undefined ;
4427-
4428- const [ branchResult , mergeBaseResult , possibleSourceBranchesResult ] = await Promise . allSettled ( [
4429- this . getBranch ( repoPath ) ,
4430- this . getMergeBase ( repoPath , 'MERGE_HEAD' , 'HEAD' ) ,
4431- this . getCommitBranches ( repoPath , [ 'MERGE_HEAD' ] , undefined , { all : true , mode : 'pointsAt' } ) ,
4432- ] ) ;
4433-
4434- const branch = getSettledValue ( branchResult ) ;
4435- const mergeBase = getSettledValue ( mergeBaseResult ) ;
4436- const possibleSourceBranches = getSettledValue ( possibleSourceBranchesResult ) ;
4437-
4438- return {
4439- type : 'merge' ,
4440- repoPath : repoPath ,
4441- mergeBase : mergeBase ,
4442- HEAD : createReference ( merge , repoPath , { refType : 'revision' } ) ,
4443- current : getReferenceFromBranch ( branch ! ) ,
4444- incoming :
4445- possibleSourceBranches ?. length === 1
4446- ? createReference ( possibleSourceBranches [ 0 ] , repoPath , {
4447- refType : 'branch' ,
4448- name : possibleSourceBranches [ 0 ] ,
4449- remote : false ,
4450- } )
4451- : undefined ,
4452- } satisfies GitMergeStatus ;
4453- }
4454-
4455- status = getCore . call ( this ) ;
4456- if ( this . useCaching ) {
4457- this . _mergeStatusCache . set ( repoPath , status ) ;
4458- }
4459- }
4460-
4461- return status ;
4425+ getPausedOperationStatus ( repoPath : string ) : Promise < GitPausedOperationStatus | undefined > {
4426+ return getPausedOperationStatus . call (
4427+ this ,
4428+ repoPath ,
4429+ this . useCaching ? this . _pausedOperationStatusCache : undefined ,
4430+ ) ;
44624431 }
44634432
44644433 @log ( )
4465- async getRebaseStatus ( repoPath : string ) : Promise < GitRebaseStatus | undefined > {
4466- let status = this . useCaching ? this . _rebaseStatusCache . get ( repoPath ) : undefined ;
4467- if ( status == null ) {
4468- async function getCore ( this : LocalGitProvider ) : Promise < GitRebaseStatus | undefined > {
4469- const gitDir = await this . getGitDir ( repoPath ) ;
4470- const [ rebaseMergeHeadResult , rebaseApplyHeadResult ] = await Promise . allSettled ( [
4471- this . git . readDotGitFile ( gitDir , [ 'rebase-merge' , 'head-name' ] ) ,
4472- this . git . readDotGitFile ( gitDir , [ 'rebase-apply' , 'head-name' ] ) ,
4473- ] ) ;
4474- const rebaseMergeHead = getSettledValue ( rebaseMergeHeadResult ) ;
4475- const rebaseApplyHead = getSettledValue ( rebaseApplyHeadResult ) ;
4476-
4477- let branch = rebaseApplyHead ?? rebaseMergeHead ;
4478- if ( branch == null ) return undefined ;
4479-
4480- const path = rebaseApplyHead != null ? 'rebase-apply' : 'rebase-merge' ;
4481-
4482- const [
4483- rebaseHeadResult ,
4484- origHeadResult ,
4485- ontoResult ,
4486- stepsNumberResult ,
4487- stepsTotalResult ,
4488- stepsMessageResult ,
4489- ] = await Promise . allSettled ( [
4490- this . git . rev_parse__verify ( repoPath , 'REBASE_HEAD' ) ,
4491- this . git . readDotGitFile ( gitDir , [ path , 'orig-head' ] ) ,
4492- this . git . readDotGitFile ( gitDir , [ path , 'onto' ] ) ,
4493- this . git . readDotGitFile ( gitDir , [ path , 'msgnum' ] , { numeric : true } ) ,
4494- this . git . readDotGitFile ( gitDir , [ path , 'end' ] , { numeric : true } ) ,
4495- this . git
4496- . readDotGitFile ( gitDir , [ path , 'message' ] , { throw : true } )
4497- . catch ( ( ) => this . git . readDotGitFile ( gitDir , [ path , 'message-squashed' ] ) ) ,
4498- ] ) ;
4499-
4500- const origHead = getSettledValue ( origHeadResult ) ;
4501- const onto = getSettledValue ( ontoResult ) ;
4502- if ( origHead == null || onto == null ) return undefined ;
4503-
4504- let mergeBase ;
4505- const rebaseHead = getSettledValue ( rebaseHeadResult ) ;
4506- if ( rebaseHead != null ) {
4507- mergeBase = await this . getMergeBase ( repoPath , rebaseHead , 'HEAD' ) ;
4508- } else {
4509- mergeBase = await this . getMergeBase ( repoPath , onto , origHead ) ;
4510- }
4511-
4512- if ( branch . startsWith ( 'refs/heads/' ) ) {
4513- branch = branch . substring ( 11 ) . trim ( ) ;
4514- }
4515-
4516- const [ branchTipsResult , tagTipsResult ] = await Promise . allSettled ( [
4517- this . getCommitBranches ( repoPath , [ onto ] , undefined , { all : true , mode : 'pointsAt' } ) ,
4518- this . getCommitTags ( repoPath , onto , { mode : 'pointsAt' } ) ,
4519- ] ) ;
4520-
4521- const branchTips = getSettledValue ( branchTipsResult ) ;
4522- const tagTips = getSettledValue ( tagTipsResult ) ;
4523-
4524- let ontoRef : GitBranchReference | GitTagReference | undefined ;
4525- if ( branchTips != null ) {
4526- for ( const ref of branchTips ) {
4527- if ( ref . startsWith ( '(no branch, rebasing' ) ) continue ;
4528-
4529- ontoRef = createReference ( ref , repoPath , {
4530- refType : 'branch' ,
4531- name : ref ,
4532- remote : false ,
4533- } ) ;
4534- break ;
4535- }
4536- }
4537- if ( ontoRef == null && tagTips != null ) {
4538- for ( const ref of tagTips ) {
4539- if ( ref . startsWith ( '(no branch, rebasing' ) ) continue ;
4540-
4541- ontoRef = createReference ( ref , repoPath , {
4542- refType : 'tag' ,
4543- name : ref ,
4544- } ) ;
4545- break ;
4546- }
4547- }
4548-
4549- return {
4550- type : 'rebase' ,
4551- repoPath : repoPath ,
4552- mergeBase : mergeBase ,
4553- HEAD : createReference ( rebaseHead ?? origHead , repoPath , { refType : 'revision' } ) ,
4554- onto : createReference ( onto , repoPath , { refType : 'revision' } ) ,
4555- current : ontoRef ,
4556- incoming : createReference ( branch , repoPath , {
4557- refType : 'branch' ,
4558- name : branch ,
4559- remote : false ,
4560- } ) ,
4561- steps : {
4562- current : {
4563- number : getSettledValue ( stepsNumberResult ) ?? 0 ,
4564- commit :
4565- rebaseHead != null
4566- ? createReference ( rebaseHead , repoPath , {
4567- refType : 'revision' ,
4568- message : getSettledValue ( stepsMessageResult ) ,
4569- } )
4570- : undefined ,
4571- } ,
4572- total : getSettledValue ( stepsTotalResult ) ?? 0 ,
4573- } ,
4574- } satisfies GitRebaseStatus ;
4575- }
4576-
4577- status = getCore . call ( this ) ;
4578- if ( this . useCaching ) {
4579- this . _rebaseStatusCache . set ( repoPath , status ) ;
4580- }
4581- }
4434+ abortPausedOperation ( repoPath : string , options ?: { quit ?: boolean } ) : Promise < void > {
4435+ return abortPausedOperation . call ( this , repoPath , options ) ;
4436+ }
45824437
4583- return status ;
4438+ @log ( )
4439+ continuePausedOperation ( repoPath : string , options ?: { skip ?: boolean } ) : Promise < void > {
4440+ return continuePausedOperation . call ( this , repoPath , options ) ;
45844441 }
45854442
45864443 @log ( )
@@ -5335,11 +5192,11 @@ export class LocalGitProvider implements GitProvider, Disposable {
53355192 const status = parseGitStatus ( data , repoPath , porcelainVersion ) ;
53365193
53375194 if ( status ?. detached ) {
5338- const rebaseStatus = await this . getRebaseStatus ( repoPath ) ;
5339- if ( rebaseStatus != null ) {
5195+ const pausedOpStatus = await this . getPausedOperationStatus ( repoPath ) ;
5196+ if ( pausedOpStatus ?. type === 'rebase' ) {
53405197 return new GitStatus (
53415198 repoPath ,
5342- rebaseStatus . incoming . name ,
5199+ pausedOpStatus . incoming . name ,
53435200 status . sha ,
53445201 status . files ,
53455202 status . state ,
0 commit comments