Pārlūkot izejas kodu

Adds more multi-root support

main
Eric Amodio pirms 7 gadiem
vecāks
revīzija
1353643fb3
8 mainītis faili ar 239 papildinājumiem un 152 dzēšanām
  1. +46
    -46
      package.json
  2. +3
    -2
      src/constants.ts
  3. +29
    -10
      src/git/gitContextTracker.ts
  4. +1
    -0
      src/git/models/models.ts
  5. +106
    -0
      src/git/models/repository.ts
  6. +42
    -83
      src/gitService.ts
  7. +1
    -1
      src/views/repositoryNode.ts
  8. +11
    -10
      src/views/statusNode.ts

+ 46
- 46
package.json Parādīt failu

@ -1243,31 +1243,31 @@
},
{
"command": "gitlens.diffWithBranch",
"when": "gitlens:isTracked"
"when": "gitlens:activeIsTracked"
},
{
"command": "gitlens.diffWithNext",
"when": "gitlens:isTracked"
"when": "gitlens:activeIsTracked"
},
{
"command": "gitlens.diffWithPrevious",
"when": "gitlens:isTracked"
"when": "gitlens:activeIsTracked"
},
{
"command": "gitlens.diffLineWithPrevious",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.diffWithRevision",
"when": "gitlens:isTracked"
"when": "gitlens:activeIsTracked"
},
{
"command": "gitlens.diffWithWorking",
"when": "gitlens:isTracked"
"when": "gitlens:activeIsTracked"
},
{
"command": "gitlens.diffLineWithWorking",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.externalDiffAll",
@ -1275,15 +1275,15 @@
},
{
"command": "gitlens.showFileBlame",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.showLineBlame",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.toggleFileBlame",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.clearFileAnnotations",
@ -1295,15 +1295,15 @@
},
{
"command": "gitlens.toggleFileRecentChanges",
"when": "gitlens:isTracked"
"when": "gitlens:activeIsTracked"
},
{
"command": "gitlens.toggleLineBlame",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.toggleCodeLens",
"when": "gitlens:isTracked && gitlens:canToggleCodeLens"
"when": "gitlens:activeIsTracked && gitlens:canToggleCodeLens"
},
{
"command": "gitlens.showLastQuickPick",
@ -1311,15 +1311,15 @@
},
{
"command": "gitlens.showQuickCommitDetails",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.showQuickCommitFileDetails",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.showQuickFileHistory",
"when": "gitlens:isTracked"
"when": "gitlens:activeIsTracked"
},
{
"command": "gitlens.showQuickBranchHistory",
@ -1339,11 +1339,11 @@
},
{
"command": "gitlens.copyShaToClipboard",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.copyMessageToClipboard",
"when": "gitlens:isBlameable"
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.closeUnchangedFiles",
@ -1355,23 +1355,23 @@
},
{
"command": "gitlens.openBranchesInRemote",
"when": "gitlens:hasRemotes"
"when": "gitlens:activeHasRemotes"
},
{
"command": "gitlens.openBranchInRemote",
"when": "gitlens:hasRemotes"
"when": "gitlens:activeHasRemotes"
},
{
"command": "gitlens.openCommitInRemote",
"when": "gitlens:isBlameable && gitlens:hasRemotes"
"when": "gitlens:activeIsBlameable && gitlens:activeHasRemotes"
},
{
"command": "gitlens.openFileInRemote",
"when": "gitlens:isTracked && gitlens:hasRemotes"
"when": "gitlens:activeIsTracked && gitlens:activeHasRemotes"
},
{
"command": "gitlens.openRepoInRemote",
"when": "gitlens:hasRemotes"
"when": "gitlens:activeHasRemotes"
},
{
"command": "gitlens.stashApply",
@ -1461,52 +1461,52 @@
"editor/context": [
{
"command": "gitlens.openFileInRemote",
"when": "editorTextFocus && gitlens:isTracked && gitlens:hasRemotes && config.gitlens.advanced.menus.editorContext.remote",
"when": "editorTextFocus && gitlens:activeHasRemotes && config.gitlens.advanced.menus.editorContext.remote",
"group": "navigation@100"
},
{
"command": "gitlens.diffLineWithPrevious",
"when": "editorTextFocus && gitlens:isBlameable && config.gitlens.advanced.menus.editorContext.lineDiff",
"when": "editorTextFocus && gitlens:activeIsBlameable && config.gitlens.advanced.menus.editorContext.lineDiff",
"group": "1_gitlens@1"
},
{
"command": "gitlens.diffLineWithWorking",
"when": "editorTextFocus && gitlens:isBlameable && config.gitlens.advanced.menus.editorContext.lineDiff",
"when": "editorTextFocus && gitlens:activeIsBlameable && config.gitlens.advanced.menus.editorContext.lineDiff",
"group": "1_gitlens@2"
},
{
"command": "gitlens.showQuickCommitFileDetails",
"when": "editorTextFocus && gitlens:isBlameable && config.gitlens.advanced.menus.editorContext.details",
"when": "editorTextFocus && gitlens:activeIsBlameable && config.gitlens.advanced.menus.editorContext.details",
"group": "1_gitlens@3"
},
{
"command": "gitlens.diffWithPrevious",
"when": "editorTextFocus && gitlens:isTracked && config.gitlens.advanced.menus.editorContext.fileDiff",
"when": "editorTextFocus && gitlens:activeIsTracked && config.gitlens.advanced.menus.editorContext.fileDiff",
"group": "1_gitlens_1@1"
},
{
"command": "gitlens.diffWithWorking",
"when": "editorTextFocus && gitlens:isTracked && config.gitlens.advanced.menus.editorContext.fileDiff",
"when": "editorTextFocus && gitlens:activeIsTracked && config.gitlens.advanced.menus.editorContext.fileDiff",
"group": "1_gitlens_1@2"
},
{
"command": "gitlens.showQuickFileHistory",
"when": "gitlens:isTracked && config.gitlens.advanced.menus.editorContext.history",
"when": "gitlens:activeIsTracked && config.gitlens.advanced.menus.editorContext.history",
"group": "3_gitlens@1"
},
{
"command": "gitlens.toggleFileBlame",
"when": "editorTextFocus && gitlens:isBlameable && config.gitlens.advanced.menus.editorContext.blame",
"when": "editorTextFocus && gitlens:activeIsBlameable && config.gitlens.advanced.menus.editorContext.blame",
"group": "3_gitlens@2"
},
{
"command": "gitlens.copyShaToClipboard",
"when": "editorTextFocus && gitlens:isBlameable && config.gitlens.advanced.menus.editorContext.copy",
"when": "editorTextFocus && gitlens:activeIsBlameable && config.gitlens.advanced.menus.editorContext.copy",
"group": "9_gitlens@1"
},
{
"command": "gitlens.copyMessageToClipboard",
"when": "editorTextFocus && gitlens:isBlameable && config.gitlens.advanced.menus.editorContext.copy",
"when": "editorTextFocus && gitlens:activeIsBlameable && config.gitlens.advanced.menus.editorContext.copy",
"group": "9_gitlens@2"
}
],
@ -1514,7 +1514,7 @@
{
"command": "gitlens.toggleFileBlame",
"alt": "gitlens.toggleFileRecentChanges",
"when": "gitlens:isBlameable && !gitlens:annotationStatus && config.gitlens.advanced.menus.editorTitle.blame",
"when": "gitlens:activeIsBlameable && !gitlens:annotationStatus && config.gitlens.advanced.menus.editorTitle.blame",
"group": "navigation@100"
},
{
@ -1529,27 +1529,27 @@
},
{
"command": "gitlens.openFileInRemote",
"when": "gitlens:enabled && gitlens:hasRemotes && config.gitlens.advanced.menus.editorTitle.remote",
"when": "gitlens:enabled && gitlens:activeHasRemotes && config.gitlens.advanced.menus.editorTitle.remote",
"group": "1_gitlens"
},
{
"command": "gitlens.openRepoInRemote",
"when": "gitlens:enabled && gitlens:hasRemotes && config.gitlens.advanced.menus.editorTitle.remote",
"when": "gitlens:enabled && gitlens:activeHasRemotes && config.gitlens.advanced.menus.editorTitle.remote",
"group": "1_gitlens"
},
{
"command": "gitlens.diffWithPrevious",
"when": "editorTextFocus && gitlens:isTracked && config.gitlens.advanced.menus.editorTitle.fileDiff",
"when": "editorTextFocus && gitlens:activeIsTracked && config.gitlens.advanced.menus.editorTitle.fileDiff",
"group": "2_gitlens"
},
{
"command": "gitlens.diffWithWorking",
"when": "editorTextFocus && gitlens:isTracked && config.gitlens.advanced.menus.editorTitle.fileDiff",
"when": "editorTextFocus && gitlens:activeIsTracked && config.gitlens.advanced.menus.editorTitle.fileDiff",
"group": "2_gitlens"
},
{
"command": "gitlens.showQuickFileHistory",
"when": "editorFocus && gitlens:isTracked && config.gitlens.advanced.menus.editorTitle.history",
"when": "editorFocus && gitlens:activeIsTracked && config.gitlens.advanced.menus.editorTitle.history",
"group": "2_gitlens_1"
},
{
@ -1990,12 +1990,12 @@
{
"command": "gitlens.toggleFileBlame",
"key": "alt+b",
"when": "editorTextFocus && gitlens:isBlameable"
"when": "editorTextFocus && gitlens:activeIsBlameable"
},
{
"command": "gitlens.toggleCodeLens",
"key": "shift+alt+b",
"when": "editorTextFocus && gitlens:isTracked && gitlens:canToggleCodeLens"
"when": "editorTextFocus && gitlens:activeIsTracked && gitlens:canToggleCodeLens"
},
{
"command": "gitlens.showLastQuickPick",
@ -2030,27 +2030,27 @@
{
"command": "gitlens.diffWithNext",
"key": "alt+.",
"when": "editorTextFocus && gitlens:isTracked"
"when": "editorTextFocus && gitlens:activeIsTracked"
},
{
"command": "gitlens.diffLineWithPrevious",
"key": "shift+alt+,",
"when": "editorTextFocus && gitlens:isTracked"
"when": "editorTextFocus && gitlens:activeIsTracked"
},
{
"command": "gitlens.diffWithPrevious",
"key": "alt+,",
"when": "editorTextFocus && gitlens:isTracked"
"when": "editorTextFocus && gitlens:activeIsTracked"
},
{
"command": "gitlens.diffLineWithWorking",
"key": "alt+w",
"when": "editorTextFocus && gitlens:isTracked"
"when": "editorTextFocus && gitlens:activeIsTracked"
},
{
"command": "gitlens.diffWithWorking",
"key": "shift+alt+w",
"when": "editorTextFocus && gitlens:isTracked"
"when": "editorTextFocus && gitlens:activeIsTracked"
}
],
"views": {

+ 3
- 2
src/constants.ts Parādīt failu

@ -33,8 +33,9 @@ export enum CommandContext {
GitExplorerView = 'gitlens:gitExplorer:view',
HasRemotes = 'gitlens:hasRemotes',
HasRepository = 'gitlens:hasRepository',
IsBlameable = 'gitlens:isBlameable',
IsTracked = 'gitlens:isTracked',
ActiveHasRemotes = 'gitlens:activeHasRemotes',
ActiveIsBlameable = 'gitlens:activeIsBlameable',
ActiveFileIsTracked = 'gitlens:activeIsTracked',
Key = 'gitlens:key'
}

+ 29
- 10
src/git/gitContextTracker.ts Parādīt failu

@ -53,7 +53,8 @@ export class GitContextTracker extends Disposable {
}
async _onRepoChanged(reasons: RepoChangedReasons[]) {
if (!reasons.includes(RepoChangedReasons.Remotes)) return;
// TODO: Support multi-root
if (!reasons.includes(RepoChangedReasons.Remotes) && !reasons.includes(RepoChangedReasons.Repositories)) return;
const gitUri = this._editor === undefined ? undefined : await GitUri.fromUri(this._editor.document.uri, this.git);
this._updateContextHasRemotes(gitUri);
@ -129,18 +130,36 @@ export class GitContextTracker extends Disposable {
private async _updateContextHasRemotes(uri: GitUri | undefined) {
try {
let repoPath = this.git.repoPath;
const repositories = await this.git.getRepositories();
let hasRemotes = false;
if (uri !== undefined && this.git.isTrackable(uri)) {
repoPath = uri.repoPath || this.git.repoPath;
const remotes = await this.git.getRemotes(uri.repoPath);
await setCommandContext(CommandContext.ActiveHasRemotes, remotes.length !== 0);
}
else {
if (repositories.length === 1) {
const remotes = await this.git.getRemotes(repositories[0].path);
hasRemotes = remotes.length !== 0;
await setCommandContext(CommandContext.ActiveHasRemotes, hasRemotes);
}
else {
await setCommandContext(CommandContext.ActiveHasRemotes, false);
}
}
let hasRemotes = false;
if (repoPath) {
const remotes = await this.git.getRemotes(repoPath);
hasRemotes = remotes.length !== 0;
if (!hasRemotes) {
for (const repo of repositories) {
const remotes = await this.git.getRemotes(repo.path);
hasRemotes = remotes.length !== 0;
if (hasRemotes) break;
}
}
setCommandContext(CommandContext.HasRemotes, hasRemotes);
await setCommandContext(CommandContext.HasRemotes, hasRemotes);
}
catch (ex) {
Logger.error(ex, 'GitEditorTracker._updateContextHasRemotes');
@ -150,7 +169,7 @@ export class GitContextTracker extends Disposable {
private async _updateEditorContext(uri: GitUri | undefined, editor: TextEditor | undefined) {
try {
const tracked = uri === undefined ? false : await this.git.isTracked(uri);
setCommandContext(CommandContext.IsTracked, tracked);
setCommandContext(CommandContext.ActiveFileIsTracked, tracked);
let blameable = tracked && (editor !== undefined && editor.document !== undefined && !editor.document.isDirty);
if (blameable) {
@ -168,7 +187,7 @@ export class GitContextTracker extends Disposable {
if (!force && this._isBlameable === blameable) return;
try {
setCommandContext(CommandContext.IsBlameable, blameable);
setCommandContext(CommandContext.ActiveIsBlameable, blameable);
this._onDidChangeBlameability.fire({
blameable: blameable,
editor: this._editor

+ 1
- 0
src/git/models/models.ts Parādīt failu

@ -7,6 +7,7 @@ export * from './diff';
export * from './log';
export * from './logCommit';
export * from './remote';
export * from './repository';
export * from './stash';
export * from './stashCommit';
export * from './status';

+ 106
- 0
src/git/models/repository.ts Parādīt failu

@ -0,0 +1,106 @@
'use strict';
import { Functions } from '../../system';
import { Disposable, Event, EventEmitter, RelativePattern, Uri, workspace, WorkspaceFolder } from 'vscode';
export enum RepositoryStorage {
StatusNode = 'statusNode'
}
export class Repository extends Disposable {
private _onDidChangeFileSystem = new EventEmitter<Uri | undefined>();
get onDidChangeFileSystem(): Event<Uri | undefined> {
return this._onDidChangeFileSystem.event;
}
readonly index: number;
readonly name: string;
readonly storage: Map<string, any> = new Map();
private readonly _disposable: Disposable;
private _fsWatcherDisposable: Disposable | undefined;
private _pendingChanges: { repo: boolean, fs: boolean } = { repo: false, fs: false };
private _suspended: boolean;
constructor(
private readonly folder: WorkspaceFolder,
public readonly path: string,
readonly onRepoChanged: (uri: Uri) => void,
suspended: boolean
) {
super(() => this.dispose());
this.index = folder.index;
this.name = folder.name;
this._suspended = suspended;
const watcher = workspace.createFileSystemWatcher(new RelativePattern(folder, '**/.git/{index,HEAD,refs/stash,refs/heads/**,refs/remotes/**}'));
const subscriptions = [
watcher,
watcher.onDidChange(onRepoChanged),
watcher.onDidCreate(onRepoChanged),
watcher.onDidDelete(onRepoChanged)
];
this._disposable = Disposable.from(...subscriptions);
}
dispose() {
this.stopWatchingFileSystem();
// Clean up any disposables in storage
for (const item of this.storage.values()) {
if (item != null && typeof item.dispose === 'function') {
item.dispose();
}
}
this._disposable && this._disposable.dispose();
}
resume() {
if (!this._suspended) return;
this._suspended = false;
// If we've come back into focus and we are dirty, fire the change events
if (this._pendingChanges.fs) {
this._pendingChanges.fs = false;
this._onDidChangeFileSystem.fire();
}
}
startWatchingFileSystem() {
if (this._fsWatcherDisposable !== undefined) return;
const debouncedFn = Functions.debounce((uri: Uri) => this._onDidChangeFileSystem.fire(uri), 2500);
const fn = (uri: Uri) => {
// Ignore .git changes
if (/\.git/.test(uri.fsPath)) return;
if (this._suspended) {
this._pendingChanges.fs = true;
return;
}
debouncedFn(uri);
};
const watcher = workspace.createFileSystemWatcher(new RelativePattern(this.folder, `**`));
this._fsWatcherDisposable = Disposable.from(
watcher,
watcher.onDidChange(fn),
watcher.onDidCreate(fn),
watcher.onDidDelete(fn)
);
}
stopWatchingFileSystem() {
this._fsWatcherDisposable && this._fsWatcherDisposable.dispose();
this._fsWatcherDisposable = undefined;
}
suspend() {
this._suspended = true;
}
}

+ 42
- 83
src/gitService.ts Parādīt failu

@ -1,10 +1,10 @@
'use strict';
import { Functions, Iterables, Objects } from './system';
import { Disposable, Event, EventEmitter, FileSystemWatcher, Range, TextDocument, TextDocumentChangeEvent, TextEditor, Uri, window, WindowState, workspace, WorkspaceFoldersChangeEvent } from 'vscode';
import { Disposable, Event, EventEmitter, Range, TextDocument, TextDocumentChangeEvent, TextEditor, Uri, window, WindowState, workspace, WorkspaceFoldersChangeEvent } from 'vscode';
import { IConfig } from './configuration';
import { CommandContext, DocumentSchemes, ExtensionKey, setCommandContext } from './constants';
import { RemoteProviderFactory } from './git/remotes/factory';
import { Git, GitAuthor, GitBlame, GitBlameCommit, GitBlameLine, GitBlameLines, GitBlameParser, GitBranch, GitBranchParser, GitCommit, GitCommitType, GitDiff, GitDiffChunkLine, GitDiffParser, GitDiffShortStat, GitLog, GitLogCommit, GitLogParser, GitRemote, GitRemoteParser, GitStash, GitStashParser, GitStatus, GitStatusFile, GitStatusParser, IGit, setDefaultEncoding } from './git/git';
import { Git, GitAuthor, GitBlame, GitBlameCommit, GitBlameLine, GitBlameLines, GitBlameParser, GitBranch, GitBranchParser, GitCommit, GitCommitType, GitDiff, GitDiffChunkLine, GitDiffParser, GitDiffShortStat, GitLog, GitLogCommit, GitLogParser, GitRemote, GitRemoteParser, GitStash, GitStashParser, GitStatus, GitStatusFile, GitStatusParser, IGit, Repository, setDefaultEncoding } from './git/git';
import { GitUri, IGitCommitInfo, IGitUriData } from './git/gitUri';
import { Logger } from './logger';
import * as fs from 'fs';
@ -51,12 +51,6 @@ interface CachedBlame extends CachedItem { }
interface CachedDiff extends CachedItem<GitDiff> { }
interface CachedLog extends CachedItem<GitLog> { }
export interface Repository {
readonly name: string;
readonly index: number;
readonly path: string;
}
enum RemoveCacheReason {
DocumentClosed,
DocumentSaved
@ -94,11 +88,7 @@ export class GitService extends Disposable {
return this._onDidChangeGitCache.event;
}
private _onDidChangeFileSystem = new EventEmitter<Uri | undefined>();
get onDidChangeFileSystem(): Event<Uri | undefined> {
return this._onDidChangeFileSystem.event;
}
// TODO: Support multi-root { repo, reasons }[]?
private _onDidChangeRepo = new EventEmitter<RepoChangedReasons[]>();
get onDidChangeRepo(): Event<RepoChangedReasons[]> {
return this._onDidChangeRepo.event;
@ -106,14 +96,13 @@ export class GitService extends Disposable {
private _cacheDisposable: Disposable | undefined;
private _disposable: Disposable | undefined;
private _focused: boolean = true;
private _gitCache: Map<string, GitCacheEntry>;
private _pendingChanges: { repo: boolean } = { repo: false };
private _remotesCache: Map<string, GitRemote[]>;
private _repositories: Map<string, Repository | undefined>;
private _repositoriesPromise: Promise<void> | undefined;
private _repoWatcher: FileSystemWatcher | undefined;
private _suspended: boolean = false;
private _trackedCache: Map<string, boolean>;
private _unfocusedChanges: { repo: boolean, fs: boolean } = { repo: false, fs: false };
private _versionedUriCache: Map<string, UriCacheEntry>;
constructor() {
@ -138,10 +127,7 @@ export class GitService extends Disposable {
}
dispose() {
this.stopWatchingFileSystem();
this._repoWatcher && this._repoWatcher.dispose();
this._repoWatcher = undefined;
this._repositories.forEach(r => r && r.dispose());
this._disposable && this._disposable.dispose();
@ -161,15 +147,6 @@ export class GitService extends Disposable {
return repo === undefined ? undefined : repo.path;
}
public async getRepositories(): Promise<Repository[]> {
if (this._repositoriesPromise !== undefined) {
await this._repositoriesPromise;
this._repositoriesPromise = undefined;
}
return [...Iterables.filter(this._repositories.values(), r => r !== undefined) as Iterable<Repository>];
}
public get UseCaching() {
return this.config.advanced.caching.enabled;
}
@ -184,15 +161,10 @@ export class GitService extends Disposable {
if (cfg.advanced.caching.enabled) {
this._cacheDisposable && this._cacheDisposable.dispose();
this._repoWatcher = this._repoWatcher || workspace.createFileSystemWatcher('**/.git/{index,HEAD,refs/stash,refs/heads/**,refs/remotes/**}');
const subscriptions: Disposable[] = [
workspace.onDidCloseTextDocument(d => this.removeCachedEntry(d, RemoveCacheReason.DocumentClosed)),
workspace.onDidChangeTextDocument(this.onTextDocumentChanged, this),
workspace.onDidSaveTextDocument(d => this.removeCachedEntry(d, RemoveCacheReason.DocumentSaved)),
this._repoWatcher.onDidChange(this.onRepoChanged, this),
this._repoWatcher.onDidCreate(this.onRepoChanged, this),
this._repoWatcher.onDidDelete(this.onRepoChanged, this)
workspace.onDidSaveTextDocument(d => this.removeCachedEntry(d, RemoveCacheReason.DocumentSaved))
];
this._cacheDisposable = Disposable.from(...subscriptions);
}
@ -200,9 +172,6 @@ export class GitService extends Disposable {
this._cacheDisposable && this._cacheDisposable.dispose();
this._cacheDisposable = undefined;
this._repoWatcher && this._repoWatcher.dispose();
this._repoWatcher = undefined;
this._gitCache.clear();
}
}
@ -223,19 +192,22 @@ export class GitService extends Disposable {
}
private onWindowStateChanged(e: WindowState) {
const focusChanged = e.focused !== this._focused;
this._focused = e.focused;
if (e.focused) {
this._repositories.forEach(r => r && r.resume());
}
else {
this._repositories.forEach(r => r && r.suspend());
}
if (!focusChanged || !e.focused) return;
const suspended = !e.focused;
const changed = suspended !== this._suspended;
this._suspended = suspended;
// If we've come back into focus and we are dirty, fire the change events
if (this._unfocusedChanges.fs) {
this._unfocusedChanges.fs = false;
this._onDidChangeFileSystem.fire();
}
if (suspended || !changed) return;
if (this._unfocusedChanges.repo) {
this._unfocusedChanges.repo = false;
// If we've come back into focus and we are dirty, fire the change events
if (this._pendingChanges.repo) {
this._pendingChanges.repo = false;
this._fireRepoChangeDebounced!();
}
}
@ -243,11 +215,9 @@ export class GitService extends Disposable {
private async onWorkspaceFoldersChanged(e?: WorkspaceFoldersChangeEvent) {
let initializing = false;
if (e === undefined) {
if (workspace.workspaceFolders === undefined) return;
initializing = true;
e = {
added: workspace.workspaceFolders,
added: workspace.workspaceFolders || [],
removed: []
} as WorkspaceFoldersChangeEvent;
}
@ -259,13 +229,21 @@ export class GitService extends Disposable {
const rp = await this.getRepoPathCore(fsPath, true);
if (rp === undefined) {
Logger.log(`onWorkspaceFoldersChanged(${fsPath})`, 'No repository found');
this._repositories.set(fsPath, undefined);
}
else {
this._repositories.set(fsPath, new Repository(f, rp, this.onRepoChanged.bind(this), this._suspended));
}
this._repositories.set(fsPath, { name: f.name, index: f.index, path: rp } as Repository);
}
for (const f of e.removed) {
if (f.uri.scheme !== DocumentSchemes.File) continue;
const repo = this._repositories.get(f.uri.fsPath);
if (repo !== undefined) {
repo.dispose();
}
this._repositories.delete(f.uri.fsPath);
}
@ -333,8 +311,8 @@ export class GitService extends Disposable {
this._repoChangedReasons.push(reason);
}
if (!this._focused) {
this._unfocusedChanges.repo = true;
if (this._suspended) {
this._pendingChanges.repo = true;
return;
}
@ -369,6 +347,15 @@ export class GitService extends Disposable {
}
}
public async getRepositories(): Promise<Repository[]> {
if (this._repositoriesPromise !== undefined) {
await this._repositoriesPromise;
this._repositoriesPromise = undefined;
}
return [...Iterables.filter(this._repositories.values(), r => r !== undefined) as Iterable<Repository>];
}
checkoutFile(uri: GitUri, sha?: string) {
sha = sha || uri.sha;
Logger.log(`checkoutFile('${uri.repoPath}', '${uri.fsPath}', ${sha})`);
@ -1111,36 +1098,8 @@ export class GitService extends Disposable {
return Git.difftool_dirDiff(repoPath, sha1, sha2);
}
private _fsWatcherDisposable: Disposable | undefined;
startWatchingFileSystem() {
if (this._fsWatcherDisposable !== undefined) return;
const debouncedFn = Functions.debounce((uri: Uri) => this._onDidChangeFileSystem.fire(uri), 2500);
const fn = (uri: Uri) => {
// Ignore .git changes
if (/\.git/.test(uri.fsPath)) return;
if (!this._focused) {
this._unfocusedChanges.fs = true;
return;
}
debouncedFn(uri);
};
const watcher = workspace.createFileSystemWatcher(`**`);
this._fsWatcherDisposable = Disposable.from(
watcher,
watcher.onDidChange(fn),
watcher.onDidCreate(fn),
watcher.onDidDelete(fn)
);
}
stopWatchingFileSystem() {
this._fsWatcherDisposable && this._fsWatcherDisposable.dispose();
this._fsWatcherDisposable = undefined;
this._repositories.forEach(r => r && r.stopWatchingFileSystem());
}
stashApply(repoPath: string, stashName: string, deleteAfter: boolean = false) {

+ 1
- 1
src/views/repositoryNode.ts Parādīt failu

@ -24,7 +24,7 @@ export class RepositoryNode extends ExplorerNode {
async getChildren(): Promise<ExplorerNode[]> {
return [
new StatusNode(this.uri, this.context, this.git),
new StatusNode(this.uri, this.repo, this.context, this.git),
new BranchesNode(this.uri, this.context, this.git),
new RemotesNode(this.uri, this.context, this.git),
new StashesNode(this.uri, this.context, this.git)

+ 11
- 10
src/views/statusNode.ts Parādīt failu

@ -1,18 +1,17 @@
import { commands, Disposable, ExtensionContext, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode';
import { commands, ExtensionContext, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode';
import { WorkspaceState } from '../constants';
import { ExplorerNode, ResourceType } from './explorerNode';
import { GitService, GitStatus, GitUri } from '../gitService';
import { GitService, GitStatus, GitUri, Repository, RepositoryStorage } from '../gitService';
import { StatusFilesNode } from './statusFilesNode';
import { StatusUpstreamNode } from './statusUpstreamNode';
let _eventDisposable: Disposable | undefined;
export class StatusNode extends ExplorerNode {
readonly resourceType: ResourceType = 'gitlens:status';
constructor(
uri: GitUri,
private repo: Repository,
protected readonly context: ExtensionContext,
protected readonly git: GitService
) {
@ -49,19 +48,21 @@ export class StatusNode extends ExplorerNode {
const status = await this.git.getStatusForRepo(this.uri.repoPath!);
if (status === undefined) return new TreeItem('No repo status');
if (_eventDisposable !== undefined) {
_eventDisposable.dispose();
_eventDisposable = undefined;
const subscription = this.repo.storage.get(RepositoryStorage.StatusNode);
if (subscription !== undefined) {
subscription.dispose();
this.repo.storage.delete(RepositoryStorage.StatusNode);
}
if (this.includeWorkingTree) {
this._status = status;
if (this.git.config.gitExplorer.autoRefresh && this.context.workspaceState.get<boolean>(WorkspaceState.GitExplorerAutoRefresh, true)) {
_eventDisposable = this.git.onDidChangeFileSystem(this.onFileSystemChanged, this);
this.context.subscriptions.push(_eventDisposable);
const subscription = this.repo.onDidChangeFileSystem(this.onFileSystemChanged, this);
this.repo.storage.set(RepositoryStorage.StatusNode, subscription);
this.context.subscriptions.push(subscription);
this.git.startWatchingFileSystem();
this.repo.startWatchingFileSystem();
}
}

Notiek ielāde…
Atcelt
Saglabāt