|
5 | 5 |
|
6 | 6 | import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType } from 'vscode'; |
7 | 7 | import { Repository as BaseRepository, Commit, Stash, GitError, Submodule, CommitOptions, ForcePushMode } from './git'; |
8 | | -import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent } from './util'; |
| 8 | +import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, toDisposable } from './util'; |
9 | 9 | import { memoize, throttle, debounce } from './decorators'; |
10 | 10 | import { toGitUri } from './uri'; |
11 | 11 | import { AutoFetcher } from './autofetch'; |
@@ -553,27 +553,28 @@ export class Repository implements Disposable { |
553 | 553 | private readonly repository: BaseRepository, |
554 | 554 | globalState: Memento |
555 | 555 | ) { |
556 | | - const fsWatcher = workspace.createFileSystemWatcher('**'); |
557 | | - this.disposables.push(fsWatcher); |
558 | | - |
559 | | - const workspaceFilter = (uri: Uri) => isDescendant(repository.root, uri.fsPath); |
560 | | - const onWorkspaceDelete = filterEvent(fsWatcher.onDidDelete, workspaceFilter); |
561 | | - const onWorkspaceChange = filterEvent(anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate), workspaceFilter); |
562 | | - const onRepositoryDotGitDelete = filterEvent(onWorkspaceDelete, uri => /\/\.git$/.test(uri.path)); |
563 | | - const onRepositoryChange = anyEvent(onWorkspaceDelete, onWorkspaceChange); |
564 | | - |
565 | | - // relevant repository changes are: |
566 | | - // - DELETE .git folder |
567 | | - // - ANY CHANGE within .git folder except .git itself and .git/index.lock |
568 | | - const onRelevantRepositoryChange = anyEvent( |
569 | | - onRepositoryDotGitDelete, |
570 | | - filterEvent(onRepositoryChange, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path)) |
571 | | - ); |
572 | | - |
573 | | - onRelevantRepositoryChange(this.onFSChange, this, this.disposables); |
574 | | - |
575 | | - const onRelevantGitChange = filterEvent(onRelevantRepositoryChange, uri => /\/\.git\//.test(uri.path)); |
576 | | - onRelevantGitChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); |
| 556 | + const workspaceWatcher = workspace.createFileSystemWatcher('**'); |
| 557 | + this.disposables.push(workspaceWatcher); |
| 558 | + |
| 559 | + const onWorkspaceFileChanges = anyEvent(workspaceWatcher.onDidChange, workspaceWatcher.onDidCreate, workspaceWatcher.onDidDelete); |
| 560 | + const onWorkspaceRepositoryFileChanges = filterEvent(onWorkspaceFileChanges, uri => isDescendant(repository.root, uri.fsPath)); |
| 561 | + const onWorkspaceWorkingTreeFileChanges = filterEvent(onWorkspaceRepositoryFileChanges, uri => !/\/\.git($|\/)/.test(uri.path)); |
| 562 | + |
| 563 | + const dotGitWatcher = fs.watch(repository.dotGit); |
| 564 | + const onRepositoryFileEmitter = new EventEmitter<Uri>(); |
| 565 | + dotGitWatcher.on('change', (_, e) => onRepositoryFileEmitter.fire(Uri.file(path.join(repository.dotGit, e as string)))); |
| 566 | + dotGitWatcher.on('error', err => console.error(err)); |
| 567 | + this.disposables.push(toDisposable(() => dotGitWatcher.close())); |
| 568 | + const onRelevantRepositoryChanges = filterEvent(onRepositoryFileEmitter.event, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path)); |
| 569 | + |
| 570 | + // FS changes should trigger `git status`: |
| 571 | + // - any change inside the repository working tree |
| 572 | + // - any change whithin the first level of the `.git` folder, except the folder itself and `index.lock` |
| 573 | + const onFSChange = anyEvent(onWorkspaceWorkingTreeFileChanges, onRelevantRepositoryChanges); |
| 574 | + onFSChange(this.onFSChange, this, this.disposables); |
| 575 | + |
| 576 | + // Relevate repository changes should trigger virtual document change events |
| 577 | + onRelevantRepositoryChanges(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); |
577 | 578 |
|
578 | 579 | const root = Uri.file(repository.root); |
579 | 580 | this._sourceControl = scm.createSourceControl('git', 'Git', root); |
|
0 commit comments