@@ -24,7 +24,7 @@ import { getLoggableName, Logger } from '../../system/logger';
2424import  {  getLogScope ,  startLogScope  }  from  '../../system/logger.scope' ; 
2525import  {  updateRecordValue  }  from  '../../system/object' ; 
2626import  {  basename ,  normalizePath  }  from  '../../system/path' ; 
27- import  type  {  GitProviderDescriptor  }  from  '../gitProvider' ; 
27+ import  type  {  GitDir ,   GitProviderDescriptor  }  from  '../gitProvider' ; 
2828import  type  {  GitRepositoryService  }  from  '../gitRepositoryService' ; 
2929import  {  getBranchNameWithoutRemote ,  getRemoteNameFromBranchName  }  from  '../utils/branch.utils' ; 
3030import  {  getReferenceNameWithoutRemote ,  isBranchReference  }  from  '../utils/reference.utils' ; 
@@ -176,6 +176,7 @@ export class Repository implements Disposable {
176176	private  _fireFileSystemChangeDebounced : Deferrable < ( )  =>  void >  |  undefined  =  undefined ; 
177177	private  _pendingFileSystemChange ?: RepositoryFileSystemChangeEvent ; 
178178	private  _pendingRepoChange ?: RepositoryChangeEvent ; 
179+ 	private  _repoWatchersDisposable : Disposable  |  undefined ; 
179180	private  _suspended : boolean ; 
180181
181182	constructor ( 
@@ -200,17 +201,12 @@ export class Repository implements Disposable {
200201			} 
201202		}  else  { 
202203			this . _name  =  basename ( uri . path ) ; 
203- 
204- 			// TODO@eamodio  should we create a fake workspace folder? 
205- 			// folder = { 
206- 			// 	uri: uri, 
207- 			// 	name: this.name, 
208- 			// 	index: container.git.repositoryCount, 
209- 			// }; 
210204		} 
211205
212- 		// Update the name if it is a worktree 
213- 		void  this . git . config . getGitDir ?.( ) . then ( gd  =>  { 
206+ 		void  this . getGitDir ( ) . then ( gd  =>  { 
207+ 			this . setupRepoWatchers ( gd ) ; 
208+ 
209+ 			// Update the name if it is a worktree 
214210			if  ( gd ?. commonUri  ==  null )  return ; 
215211
216212			let  path  =  gd . commonUri . path ; 
@@ -235,46 +231,7 @@ export class Repository implements Disposable {
235231		this . _disposable  =  Disposable . from ( 
236232			this . _onDidChange , 
237233			this . _onDidChangeFileSystem , 
238- 			this . setupRepoWatchers ( ) , 
239234			configuration . onDidChange ( this . onConfigurationChanged ,  this ) , 
240- 			// Sending this event in the `'git:cache:reset'` below to avoid unnecessary work. While we will refresh more than needed, this doesn't happen often 
241- 			// container.richRemoteProviders.onAfterDidChangeConnectionState(async e => { 
242- 			// 	const uniqueKeys = new Set<string>(); 
243- 			// 	for (const remote of await this.getRemotes()) { 
244- 			// 		if (remote.provider?.hasRichIntegration()) { 
245- 			// 			uniqueKeys.add(remote.provider.key); 
246- 			// 		} 
247- 			// 	} 
248- 
249- 			// 	if (uniqueKeys.has(e.key)) { 
250- 			// 		this.fireChange(RepositoryChange.RemoteProviders); 
251- 			// 	} 
252- 			// }), 
253- 		) ; 
254- 
255- 		this . onConfigurationChanged ( ) ; 
256- 		if  ( this . _orderByLastFetched )  { 
257- 			void  this . getLastFetched ( ) ; 
258- 		} 
259- 	} 
260- 
261- 	private  setupRepoWatchers ( )  { 
262- 		let  disposable : Disposable  |  undefined ; 
263- 
264- 		void  this . setupRepoWatchersCore ( ) . then ( d  =>  ( disposable  =  d ) ) ; 
265- 
266- 		return  { 
267- 			dispose : ( )  =>  void  disposable ?. dispose ( ) , 
268- 		} ; 
269- 	} 
270- 
271- 	@debug ( {  singleLine : true  } ) 
272- 	private  async  setupRepoWatchersCore ( )  { 
273- 		const  scope  =  getLogScope ( ) ; 
274- 
275- 		const  disposables : Disposable [ ]  =  [ ] ; 
276- 
277- 		disposables . push ( 
278235			this . container . events . on ( 'git:cache:reset' ,  e  =>  { 
279236				if  ( ! e . data . repoPath  ||  e . data . repoPath  ===  this . path )  { 
280237					if  ( e . data . types ?. includes ( 'providers' ) )  { 
@@ -289,44 +246,15 @@ export class Repository implements Disposable {
289246			} ) , 
290247		) ; 
291248
292- 		const  watcher  =  workspace . createFileSystemWatcher ( new  RelativePattern ( this . uri ,  '**/.gitignore' ) ) ; 
293- 		disposables . push ( 
294- 			watcher , 
295- 			watcher . onDidChange ( this . onGitIgnoreChanged ,  this ) , 
296- 			watcher . onDidCreate ( this . onGitIgnoreChanged ,  this ) , 
297- 			watcher . onDidDelete ( this . onGitIgnoreChanged ,  this ) , 
298- 		) ; 
299- 
300- 		function  watch ( this : Repository ,  uri : Uri ,  pattern : string )  { 
301- 			Logger . debug ( scope ,  `watching '${ uri . toString ( true ) }  ' for repository changes` ) ; 
302- 
303- 			const  watcher  =  workspace . createFileSystemWatcher ( new  RelativePattern ( uri ,  pattern ) ) ; 
304- 
305- 			disposables . push ( 
306- 				watcher , 
307- 				watcher . onDidChange ( e  =>  this . onRepositoryChanged ( e ,  uri ,  'change' ) ) , 
308- 				watcher . onDidCreate ( e  =>  this . onRepositoryChanged ( e ,  uri ,  'create' ) ) , 
309- 				watcher . onDidDelete ( e  =>  this . onRepositoryChanged ( e ,  uri ,  'delete' ) ) , 
310- 			) ; 
311- 			return  watcher ; 
312- 		} 
313- 
314- 		const  gitDir  =  await  this . git . config . getGitDir ?.( ) ; 
315- 		if  ( gitDir  !=  null )  { 
316- 			if  ( gitDir ?. commonUri  ==  null )  { 
317- 				watch . call ( this ,  gitDir . uri ,  dotGitWatcherGlobCombined ) ; 
318- 			}  else  { 
319- 				watch . call ( this ,  gitDir . uri ,  dotGitWatcherGlobRoot ) ; 
320- 				watch . call ( this ,  gitDir . commonUri ,  dotGitWatcherGlobCommon ) ; 
321- 			} 
249+ 		this . onConfigurationChanged ( ) ; 
250+ 		if  ( this . _orderByLastFetched )  { 
251+ 			void  this . getLastFetched ( ) ; 
322252		} 
323- 
324- 		return  Disposable . from ( ...disposables ) ; 
325253	} 
326254
327255	dispose ( ) : void   { 
328256		this . unWatchFileSystem ( true ) ; 
329- 
257+ 		 this . _repoWatchersDisposable ?. dispose ( ) ; 
330258		this . _disposable . dispose ( ) ; 
331259	} 
332260
@@ -344,6 +272,7 @@ export class Repository implements Disposable {
344272		if  ( changed )  { 
345273			using scope  =  startLogScope ( `${ getLoggableName ( this ) }  .closed` ,  false ) ; 
346274			Logger . debug ( scope ,  `setting closed=${ value }  ` ) ; 
275+ 			void  this . getGitDir ( ) . then ( gd  =>  this . setupRepoWatchers ( gd ) ) ; 
347276			this . fireChange ( this . _closed  ? RepositoryChange . Closed  : RepositoryChange . Opened ) ; 
348277		} 
349278	} 
@@ -601,7 +530,7 @@ export class Repository implements Disposable {
601530
602531	@log ( {  exit : true  } ) 
603532	async  getCommonRepositoryUri ( ) : Promise < Uri  |  undefined >  { 
604- 		const  gitDir  =  await  this . git . config . getGitDir ?. ( ) ; 
533+ 		const  gitDir  =  await  this . getGitDir ( ) ; 
605534		if  ( gitDir ?. commonUri ?. path . endsWith ( '/.git' ) )  { 
606535			return  gitDir . commonUri . with ( { 
607536				path : gitDir . commonUri . path . substring ( 0 ,  gitDir . commonUri . path . length  -  5 ) , 
@@ -1008,11 +937,75 @@ export class Repository implements Disposable {
1008937		this . _onDidChangeFileSystem . fire ( e ) ; 
1009938	} 
1010939
940+ 	private  _gitDirPromise : Promise < GitDir  |  undefined >  |  undefined ; 
941+ 	private  async  getGitDir ( ) : Promise < GitDir  |  undefined >  { 
942+ 		return  ( this . _gitDirPromise  ??=  this . git . config . getGitDir ?.( ) ) ; 
943+ 	} 
944+ 
1011945	private  async  runTerminalCommand ( command : string ,  ...args : string [ ] )  { 
1012946		await  this . git . runGitCommandViaTerminal ?.( command ,  args ,  {  execute : true  } ) ; 
1013947
1014948		setTimeout ( ( )  =>  this . fireChange ( RepositoryChange . Unknown ) ,  2500 ) ; 
1015949	} 
950+ 
951+ 	@debug ( {  singleLine : true  } ) 
952+ 	private  setupRepoWatchers ( gitDir : GitDir  |  undefined ) : void   { 
953+ 		const  scope  =  getLogScope ( ) ; 
954+ 
955+ 		if  ( this . closed )  { 
956+ 			if  ( this . _repoWatchersDisposable  !=  null )  { 
957+ 				Logger . debug ( 
958+ 					getLogScope ( ) , 
959+ 					`(closed) stop watching '${ this . uri . toString ( true ) }  ' for repository changes` , 
960+ 				) ; 
961+ 				this . _repoWatchersDisposable . dispose ( ) ; 
962+ 				this . _repoWatchersDisposable  =  undefined ; 
963+ 			} 
964+ 
965+ 			return ; 
966+ 		} 
967+ 
968+ 		if  ( this . _repoWatchersDisposable  !=  null )  return ; 
969+ 
970+ 		const  disposables : Disposable [ ]  =  [ ] ; 
971+ 
972+ 		// If the repository is not part of the workspace, then limit watching to only the .gitignore file at the root of the repository 
973+ 		const  gitIgnorePattern  =  this . folder  !=  null  ? '**/.gitignore'  : '.gitignore' ; 
974+ 		Logger . debug ( scope ,  `watching '${ this . uri . toString ( true ) }  /${ gitIgnorePattern }  ' for .gitignore changes` ) ; 
975+ 
976+ 		const  watcher  =  workspace . createFileSystemWatcher ( new  RelativePattern ( this . uri ,  gitIgnorePattern ) ) ; 
977+ 		disposables . push ( 
978+ 			watcher , 
979+ 			watcher . onDidChange ( this . onGitIgnoreChanged ,  this ) , 
980+ 			watcher . onDidCreate ( this . onGitIgnoreChanged ,  this ) , 
981+ 			watcher . onDidDelete ( this . onGitIgnoreChanged ,  this ) , 
982+ 		) ; 
983+ 
984+ 		function  watch ( this : Repository ,  uri : Uri ,  pattern : string )  { 
985+ 			Logger . debug ( scope ,  `watching '${ uri . toString ( true ) }  /${ pattern }  ' for repository changes` ) ; 
986+ 
987+ 			const  watcher  =  workspace . createFileSystemWatcher ( new  RelativePattern ( uri ,  pattern ) ) ; 
988+ 
989+ 			disposables . push ( 
990+ 				watcher , 
991+ 				watcher . onDidChange ( e  =>  this . onRepositoryChanged ( e ,  uri ,  'change' ) ) , 
992+ 				watcher . onDidCreate ( e  =>  this . onRepositoryChanged ( e ,  uri ,  'create' ) ) , 
993+ 				watcher . onDidDelete ( e  =>  this . onRepositoryChanged ( e ,  uri ,  'delete' ) ) , 
994+ 			) ; 
995+ 			return  watcher ; 
996+ 		} 
997+ 
998+ 		if  ( gitDir  !=  null )  { 
999+ 			if  ( gitDir ?. commonUri  ==  null )  { 
1000+ 				watch . call ( this ,  gitDir . uri ,  dotGitWatcherGlobCombined ) ; 
1001+ 			}  else  { 
1002+ 				watch . call ( this ,  gitDir . uri ,  dotGitWatcherGlobRoot ) ; 
1003+ 				watch . call ( this ,  gitDir . commonUri ,  dotGitWatcherGlobCommon ) ; 
1004+ 			} 
1005+ 		} 
1006+ 
1007+ 		this . _repoWatchersDisposable  =  Disposable . from ( ...disposables ) ; 
1008+ 	} 
10161009} 
10171010
10181011export  function  isRepository ( repository : unknown ) : repository  is Repository  { 
0 commit comments