diff --git a/extensions/git/package.json b/extensions/git/package.json index 3173dfddf52..491e5ca4390 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -276,393 +276,393 @@ }, { "command": "git.init", - "when": "config.git.enabled && scmProvider == git && gitState == norepo" + "when": "config.git.enabled" }, { "command": "git.refresh", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.openFile", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.openHEADFile", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.openChange", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.stage", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.stageAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.stageSelectedRanges", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.revertSelectedRanges", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.unstage", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.unstageAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.unstageSelectedRanges", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.clean", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.cleanAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.commit", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.commitStaged", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.commitStagedSigned", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.commitStagedAmend", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.commitAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.commitAllSigned", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.commitAllAmend", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.undoCommit", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.checkout", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.branch", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.deleteBranch", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.pull", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.pullFrom", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.pullRebase", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.pullFrom", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.createTag", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.push", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.pushTo", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.pushWithTags", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.sync", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.publish", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.showOutput", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.stash", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.stashPop", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" }, { "command": "git.stashPopLatest", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled" } ], "scm/title": [ { "command": "git.init", "group": "navigation", - "when": "config.git.enabled && scmProvider == git && gitState == norepo" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.commit", "group": "navigation", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.refresh", "group": "navigation", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.sync", "group": "1_sync", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.pull", "group": "1_sync", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.pullRebase", "group": "1_sync", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.pullFrom", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.push", "group": "1_sync", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.pushTo", "group": "1_sync", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.publish", "group": "2_publish", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.commitStaged", "group": "3_commit", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.commitStagedSigned", "group": "3_commit", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.commitStagedAmend", "group": "3_commit", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.commitAll", "group": "3_commit", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.commitAllSigned", "group": "3_commit", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.commitAllAmend", "group": "3_commit", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.undoCommit", "group": "3_commit", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.unstageAll", "group": "4_stage", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.cleanAll", "group": "4_stage", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.showOutput", "group": "6_output", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.stash", "group": "5_stash", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.stashPop", "group": "5_stash", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" }, { "command": "git.stashPopLatest", "group": "5_stash", - "when": "config.git.enabled && scmProvider == git && gitState == idle" + "when": "config.git.enabled && scmProvider == git" } ], "scm/resourceGroup/context": [ { "command": "git.stageAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == merge", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == merge", "group": "1_modification" }, { "command": "git.stageAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == merge", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == merge", "group": "inline" }, { "command": "git.unstageAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == index", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == index", "group": "1_modification" }, { "command": "git.unstageAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == index", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == index", "group": "inline" }, { "command": "git.cleanAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "1_modification" }, { "command": "git.stageAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "1_modification" }, { "command": "git.cleanAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "inline" }, { "command": "git.stageAll", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "inline" } ], "scm/resourceState/context": [ { "command": "git.stage", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == merge", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == merge", "group": "1_modification" }, { "command": "git.stage", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == merge", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == merge", "group": "inline" }, { "command": "git.openChange", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == index", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == index", "group": "navigation" }, { "command": "git.openFile", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == index", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == index", "group": "navigation" }, { "command": "git.openHEADFile", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == index", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == index", "group": "navigation" }, { "command": "git.unstage", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == index", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == index", "group": "1_modification" }, { "command": "git.unstage", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == index", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == index", "group": "inline" }, { "command": "git.openChange", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "navigation" }, { "command": "git.openHEADFile", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "navigation" }, { "command": "git.openFile", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "navigation" }, { "command": "git.stage", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "1_modification" }, { "command": "git.clean", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "1_modification" }, { "command": "git.clean", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "inline" }, { "command": "git.stage", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "inline" }, { "command": "git.ignore", - "when": "config.git.enabled && scmProvider == git && gitState == idle && scmResourceGroup == workingTree", + "when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree", "group": "1_modification@3" } ], diff --git a/extensions/git/src/autofetch.ts b/extensions/git/src/autofetch.ts index 3e119e9fec7..930fc2f05f3 100644 --- a/extensions/git/src/autofetch.ts +++ b/extensions/git/src/autofetch.ts @@ -16,7 +16,7 @@ export class AutoFetcher { private disposables: Disposable[] = []; private timer: NodeJS.Timer; - constructor(private model: Repository) { + constructor(private repository: Repository) { workspace.onDidChangeConfiguration(this.onConfiguration, this, this.disposables); this.onConfiguration(); } @@ -47,7 +47,7 @@ export class AutoFetcher { @throttle private async fetch(): Promise { try { - await this.model.fetch(); + await this.repository.fetch(); } catch (err) { if (err.gitErrorCode === GitErrorCodes.AuthenticationFailed) { this.disable(); diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 76b79736b3d..29a036a726a 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -7,7 +7,7 @@ import { Uri, commands, scm, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn } from 'vscode'; import { Ref, RefType, Git, GitErrorCodes, Branch } from './git'; -import { Repository, Resource, Status, CommitOptions, WorkingTreeGroup, IndexGroup, MergeGroup } from './repository'; +import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository'; import { Model } from './model'; import { toGitUri, fromGitUri } from './uri'; import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange } from './staging'; @@ -27,14 +27,14 @@ class CheckoutItem implements QuickPickItem { constructor(protected ref: Ref) { } - async run(model: Repository): Promise { + async run(repository: Repository): Promise { const ref = this.treeish; if (!ref) { return; } - await model.checkout(ref); + await repository.checkout(ref); } } @@ -70,11 +70,11 @@ class BranchDeleteItem implements QuickPickItem { constructor(private ref: Ref) { } - async run(model: Repository, force?: boolean): Promise { + async run(repository: Repository, force?: boolean): Promise { if (!this.branchName) { return; } - await model.deleteBranch(this.branchName, force); + await repository.deleteBranch(this.branchName, force); } } @@ -85,8 +85,8 @@ class MergeItem implements QuickPickItem { constructor(protected ref: Ref) { } - async run(model: Repository): Promise { - await model.merge(this.ref.name! || this.ref.commit!); + async run(repository: Repository): Promise { + await repository.merge(this.ref.name! || this.ref.commit!); } } @@ -95,7 +95,7 @@ class CreateBranchItem implements QuickPickItem { get label(): string { return localize('create branch', '$(plus) Create new branch'); } get description(): string { return ''; } - async run(model: Repository): Promise { + async run(repository: Repository): Promise { await commands.executeCommand('git.branch'); } } @@ -146,18 +146,18 @@ export class CommandCenter { } @command('git.refresh', { model: true }) - async refresh(model: Repository): Promise { - await model.status(); + async refresh(repository: Repository): Promise { + await repository.status(); } @command('git.openResource', { model: true }) - async openResource(model: Repository, resource: Resource): Promise { - await this._openResource(model, resource); + async openResource(repository: Repository, resource: Resource): Promise { + await this._openResource(repository, resource); } - private async _openResource(model: Repository, resource: Resource, preview?: boolean): Promise { + private async _openResource(repository: Repository, resource: Resource, preview?: boolean): Promise { const left = this.getLeftResource(resource); - const right = this.getRightResource(model, resource); + const right = this.getRightResource(repository, resource); const title = this.getTitle(resource); if (!right) { @@ -201,7 +201,7 @@ export class CommandCenter { } } - private getRightResource(model: Repository, resource: Resource): Uri | undefined { + private getRightResource(repository: Repository, resource: Resource): Uri | undefined { switch (resource.type) { case Status.INDEX_MODIFIED: case Status.INDEX_ADDED: @@ -218,7 +218,7 @@ export class CommandCenter { case Status.UNTRACKED: case Status.IGNORED: const uriString = resource.resourceUri.toString(); - const [indexStatus] = model.indexGroup.resources.filter(r => r.resourceUri.toString() === uriString); + const [indexStatus] = repository.indexGroup.resourceStates.filter(r => r.resourceUri.toString() === uriString); if (indexStatus && indexStatus.renameResourceUri) { return indexStatus.renameResourceUri; @@ -307,7 +307,7 @@ export class CommandCenter { } @command('git.openFile', { model: true }) - async openFile(model: Repository, arg?: Resource | Uri, ...resourceStates: SourceControlResourceState[]): Promise { + async openFile(repository: Repository, arg?: Resource | Uri, ...resourceStates: SourceControlResourceState[]): Promise { let uris: Uri[] | undefined; if (arg instanceof Uri) { @@ -357,7 +357,7 @@ export class CommandCenter { } @command('git.openHEADFile', { model: true }) - async openHEADFile(model: Repository, arg?: Resource | Uri): Promise { + async openHEADFile(repository: Repository, arg?: Resource | Uri): Promise { let resource: Resource | undefined = undefined; if (arg instanceof Resource) { @@ -383,7 +383,7 @@ export class CommandCenter { } @command('git.openChange', { model: true }) - async openChange(model: Repository, arg?: Resource | Uri, ...resourceStates: SourceControlResourceState[]): Promise { + async openChange(repository: Repository, arg?: Resource | Uri, ...resourceStates: SourceControlResourceState[]): Promise { let resources: Resource[] | undefined = undefined; if (arg instanceof Uri) { @@ -411,7 +411,7 @@ export class CommandCenter { const preview = resources.length === 1 ? undefined : false; for (const resource of resources) { - await this._openResource(model, resource, preview); + await this._openResource(repository, resource, preview); } } @@ -428,7 +428,7 @@ export class CommandCenter { } const scmResources = resourceStates - .filter(s => s instanceof Resource && (s.resourceGroup instanceof WorkingTreeGroup || s.resourceGroup instanceof MergeGroup)) as Resource[]; + .filter(s => s instanceof Resource && (s.resourceGroupType === ResourceGroupType.WorkingTree || s.resourceGroupType === ResourceGroupType.Merge)) as Resource[]; if (!scmResources.length) { return; @@ -439,13 +439,13 @@ export class CommandCenter { } @command('git.stageAll', { model: true }) - async stageAll(model: Repository): Promise { - await model.add([]); + async stageAll(repository: Repository): Promise { + await repository.add([]); } // TODO@Joao does this command really receive a model? @command('git.stageSelectedRanges', { model: true, diff: true }) - async stageSelectedRanges(model: Repository, diffs: LineChange[]): Promise { + async stageSelectedRanges(repository: Repository, diffs: LineChange[]): Promise { const textEditor = window.activeTextEditor; if (!textEditor) { @@ -472,12 +472,12 @@ export class CommandCenter { const result = applyLineChanges(originalDocument, modifiedDocument, selectedDiffs); - await model.stage(modifiedUri, result); + await repository.stage(modifiedUri, result); } // TODO@Joao does this command really receive a model? @command('git.revertSelectedRanges', { model: true, diff: true }) - async revertSelectedRanges(model: Repository, diffs: LineChange[]): Promise { + async revertSelectedRanges(repository: Repository, diffs: LineChange[]): Promise { const textEditor = window.activeTextEditor; if (!textEditor) { @@ -522,7 +522,7 @@ export class CommandCenter { } @command('git.unstage', { model: true }) - async unstage(model: Repository, ...resourceStates: SourceControlResourceState[]): Promise { + async unstage(repository: Repository, ...resourceStates: SourceControlResourceState[]): Promise { if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) { const resource = this.getSCMResource(); @@ -534,7 +534,7 @@ export class CommandCenter { } const scmResources = resourceStates - .filter(s => s instanceof Resource && s.resourceGroup instanceof IndexGroup) as Resource[]; + .filter(s => s instanceof Resource && s.resourceGroupType === ResourceGroupType.Index) as Resource[]; if (!scmResources.length) { return; @@ -542,17 +542,17 @@ export class CommandCenter { const resources = scmResources.map(r => r.resourceUri); - return await model.revert(resources); + return await repository.revert(resources); } @command('git.unstageAll', { model: true }) - async unstageAll(model: Repository): Promise { - return await model.revert([]); + async unstageAll(repository: Repository): Promise { + return await repository.revert([]); } // TODO@Joao does this command really receive a model? @command('git.unstageSelectedRanges', { model: true, diff: true }) - async unstageSelectedRanges(model: Repository, diffs: LineChange[]): Promise { + async unstageSelectedRanges(repository: Repository, diffs: LineChange[]): Promise { const textEditor = window.activeTextEditor; if (!textEditor) { @@ -586,11 +586,11 @@ export class CommandCenter { const invertedDiffs = selectedDiffs.map(invertLineChange); const result = applyLineChanges(modifiedDocument, originalDocument, invertedDiffs); - await model.stage(modifiedUri, result); + await repository.stage(modifiedUri, result); } @command('git.clean', { model: true }) - async clean(model: Repository, ...resourceStates: SourceControlResourceState[]): Promise { + async clean(repository: Repository, ...resourceStates: SourceControlResourceState[]): Promise { if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) { const resource = this.getSCMResource(); @@ -602,7 +602,7 @@ export class CommandCenter { } const resources = resourceStates - .filter(s => s instanceof Resource && s.resourceGroup instanceof WorkingTreeGroup) as Resource[]; + .filter(s => s instanceof Resource && s.resourceGroupType === ResourceGroupType.WorkingTree) as Resource[]; if (!resources.length) { return; @@ -633,14 +633,14 @@ export class CommandCenter { return; } - await model.clean(resources.map(r => r.resourceUri)); + await repository.clean(resources.map(r => r.resourceUri)); } @command('git.cleanAll', { model: true }) - async cleanAll(model: Repository): Promise { + async cleanAll(repository: Repository): Promise { const config = workspace.getConfiguration('git'); let scope = config.get('discardAllScope') || 'prompt'; - let resources = model.workingTreeGroup.resources; + let resources = repository.workingTreeGroup.resourceStates; if (resources.length === 0) { return; @@ -685,19 +685,19 @@ export class CommandCenter { return; } - await model.clean(resources.map(r => r.resourceUri)); + await repository.clean(resources.map(r => r.resourceUri)); } private async smartCommit( - model: Repository, + repository: Repository, getCommitMessage: () => Promise, opts?: CommitOptions ): Promise { const config = workspace.getConfiguration('git'); const enableSmartCommit = config.get('enableSmartCommit') === true; const enableCommitSigning = config.get('enableCommitSigning') === true; - const noStagedChanges = model.indexGroup.resources.length === 0; - const noUnstagedChanges = model.workingTreeGroup.resources.length === 0; + const noStagedChanges = repository.indexGroup.resourceStates.length === 0; + const noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0; // no changes, and the user has not configured to commit all in this case if (!noUnstagedChanges && noStagedChanges && !enableSmartCommit) { @@ -739,12 +739,12 @@ export class CommandCenter { return false; } - await model.commit(message, opts); + await repository.commit(message, opts); return true; } - private async commitWithAnyInput(model: Repository, opts?: CommitOptions): Promise { + private async commitWithAnyInput(repository: Repository, opts?: CommitOptions): Promise { const message = scm.inputBox.value; const getCommitMessage = async () => { if (message) { @@ -758,78 +758,78 @@ export class CommandCenter { }); }; - const didCommit = await this.smartCommit(model, getCommitMessage, opts); + const didCommit = await this.smartCommit(repository, getCommitMessage, opts); if (message && didCommit) { - scm.inputBox.value = await model.getCommitTemplate(); + scm.inputBox.value = await repository.getCommitTemplate(); } } @command('git.commit', { model: true }) - async commit(model: Repository): Promise { - await this.commitWithAnyInput(model); + async commit(repository: Repository): Promise { + await this.commitWithAnyInput(repository); } @command('git.commitWithInput', { model: true }) - async commitWithInput(model: Repository): Promise { + async commitWithInput(repository: Repository): Promise { if (!scm.inputBox.value) { return; } - const didCommit = await this.smartCommit(model, async () => scm.inputBox.value); + const didCommit = await this.smartCommit(repository, async () => scm.inputBox.value); if (didCommit) { - scm.inputBox.value = await model.getCommitTemplate(); + scm.inputBox.value = await repository.getCommitTemplate(); } } @command('git.commitStaged', { model: true }) - async commitStaged(model: Repository): Promise { - await this.commitWithAnyInput(model, { all: false }); + async commitStaged(repository: Repository): Promise { + await this.commitWithAnyInput(repository, { all: false }); } @command('git.commitStagedSigned', { model: true }) - async commitStagedSigned(model: Repository): Promise { - await this.commitWithAnyInput(model, { all: false, signoff: true }); + async commitStagedSigned(repository: Repository): Promise { + await this.commitWithAnyInput(repository, { all: false, signoff: true }); } @command('git.commitStagedAmend', { model: true }) - async commitStagedAmend(model: Repository): Promise { - await this.commitWithAnyInput(model, { all: false, amend: true }); + async commitStagedAmend(repository: Repository): Promise { + await this.commitWithAnyInput(repository, { all: false, amend: true }); } @command('git.commitAll', { model: true }) - async commitAll(model: Repository): Promise { - await this.commitWithAnyInput(model, { all: true }); + async commitAll(repository: Repository): Promise { + await this.commitWithAnyInput(repository, { all: true }); } @command('git.commitAllSigned', { model: true }) - async commitAllSigned(model: Repository): Promise { - await this.commitWithAnyInput(model, { all: true, signoff: true }); + async commitAllSigned(repository: Repository): Promise { + await this.commitWithAnyInput(repository, { all: true, signoff: true }); } @command('git.commitAllAmend', { model: true }) - async commitAllAmend(model: Repository): Promise { - await this.commitWithAnyInput(model, { all: true, amend: true }); + async commitAllAmend(repository: Repository): Promise { + await this.commitWithAnyInput(repository, { all: true, amend: true }); } @command('git.undoCommit', { model: true }) - async undoCommit(model: Repository): Promise { - const HEAD = model.HEAD; + async undoCommit(repository: Repository): Promise { + const HEAD = repository.HEAD; if (!HEAD || !HEAD.commit) { return; } - const commit = await model.getCommit('HEAD'); - await model.reset('HEAD~'); + const commit = await repository.getCommit('HEAD'); + await repository.reset('HEAD~'); scm.inputBox.value = commit.message; } @command('git.checkout', { model: true }) - async checkout(model: Repository, treeish: string): Promise { + async checkout(repository: Repository, treeish: string): Promise { if (typeof treeish === 'string') { - return await model.checkout(treeish); + return await repository.checkout(treeish); } const config = workspace.getConfiguration('git'); @@ -839,13 +839,13 @@ export class CommandCenter { const createBranch = new CreateBranchItem(); - const heads = model.refs.filter(ref => ref.type === RefType.Head) + const heads = repository.refs.filter(ref => ref.type === RefType.Head) .map(ref => new CheckoutItem(ref)); - const tags = (includeTags ? model.refs.filter(ref => ref.type === RefType.Tag) : []) + const tags = (includeTags ? repository.refs.filter(ref => ref.type === RefType.Tag) : []) .map(ref => new CheckoutTagItem(ref)); - const remoteHeads = (includeRemotes ? model.refs.filter(ref => ref.type === RefType.RemoteHead) : []) + const remoteHeads = (includeRemotes ? repository.refs.filter(ref => ref.type === RefType.RemoteHead) : []) .map(ref => new CheckoutRemoteHeadItem(ref)); const picks = [createBranch, ...heads, ...tags, ...remoteHeads]; @@ -856,11 +856,11 @@ export class CommandCenter { return; } - await choice.run(model); + await choice.run(repository); } @command('git.branch', { model: true }) - async branch(model: Repository): Promise { + async branch(repository: Repository): Promise { const result = await window.showInputBox({ placeHolder: localize('branch name', "Branch name"), prompt: localize('provide branch name', "Please provide a branch name"), @@ -872,17 +872,17 @@ export class CommandCenter { } const name = result.replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$/g, '-'); - await model.branch(name); + await repository.branch(name); } @command('git.deleteBranch', { model: true }) - async deleteBranch(model: Repository, name: string, force?: boolean): Promise { + async deleteBranch(repository: Repository, name: string, force?: boolean): Promise { let run: (force?: boolean) => Promise; if (typeof name === 'string') { - run = force => model.deleteBranch(name, force); + run = force => repository.deleteBranch(name, force); } else { - const currentHead = model.HEAD && model.HEAD.name; - const heads = model.refs.filter(ref => ref.type === RefType.Head && ref.name !== currentHead) + const currentHead = repository.HEAD && repository.HEAD.name; + const heads = repository.refs.filter(ref => ref.type === RefType.Head && ref.name !== currentHead) .map(ref => new BranchDeleteItem(ref)); const placeHolder = localize('select branch to delete', 'Select a branch to delete'); @@ -892,7 +892,7 @@ export class CommandCenter { return; } name = choice.branchName; - run = force => choice.run(model, force); + run = force => choice.run(repository, force); } try { @@ -913,16 +913,16 @@ export class CommandCenter { } @command('git.merge', { model: true }) - async merge(model: Repository): Promise { + async merge(repository: Repository): Promise { const config = workspace.getConfiguration('git'); const checkoutType = config.get('checkoutType') || 'all'; const includeRemotes = checkoutType === 'all' || checkoutType === 'remote'; - const heads = model.refs.filter(ref => ref.type === RefType.Head) + const heads = repository.refs.filter(ref => ref.type === RefType.Head) .filter(ref => ref.name || ref.commit) .map(ref => new MergeItem(ref as Branch)); - const remoteHeads = (includeRemotes ? model.refs.filter(ref => ref.type === RefType.RemoteHead) : []) + const remoteHeads = (includeRemotes ? repository.refs.filter(ref => ref.type === RefType.RemoteHead) : []) .filter(ref => ref.name || ref.commit) .map(ref => new MergeItem(ref as Branch)); @@ -935,7 +935,7 @@ export class CommandCenter { } try { - await choice.run(model); + await choice.run(repository); } catch (err) { if (err.gitErrorCode !== GitErrorCodes.Conflict) { throw err; @@ -947,7 +947,7 @@ export class CommandCenter { } @command('git.createTag', { model: true }) - async createTag(model: Repository): Promise { + async createTag(repository: Repository): Promise { const inputTagName = await window.showInputBox({ placeHolder: localize('tag name', "Tag name"), prompt: localize('provide tag name', "Please provide a tag name"), @@ -966,12 +966,12 @@ export class CommandCenter { const name = inputTagName.replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$/g, '-'); const message = inputMessage || name; - await model.tag(name, message); + await repository.tag(name, message); } @command('git.pullFrom', { model: true }) - async pullFrom(model: Repository): Promise { - const remotes = model.remotes; + async pullFrom(repository: Repository): Promise { + const remotes = repository.remotes; if (remotes.length === 0) { window.showWarningMessage(localize('no remotes to pull', "Your repository has no remotes configured to pull from.")); @@ -996,74 +996,74 @@ export class CommandCenter { return; } - model.pull(false, pick.label, branchName); + repository.pull(false, pick.label, branchName); } @command('git.pull', { model: true }) - async pull(model: Repository): Promise { - const remotes = model.remotes; + async pull(repository: Repository): Promise { + const remotes = repository.remotes; if (remotes.length === 0) { window.showWarningMessage(localize('no remotes to pull', "Your repository has no remotes configured to pull from.")); return; } - await model.pull(); + await repository.pull(); } @command('git.pullRebase', { model: true }) - async pullRebase(model: Repository): Promise { - const remotes = model.remotes; + async pullRebase(repository: Repository): Promise { + const remotes = repository.remotes; if (remotes.length === 0) { window.showWarningMessage(localize('no remotes to pull', "Your repository has no remotes configured to pull from.")); return; } - await model.pullWithRebase(); + await repository.pullWithRebase(); } @command('git.push', { model: true }) - async push(model: Repository): Promise { - const remotes = model.remotes; + async push(repository: Repository): Promise { + const remotes = repository.remotes; if (remotes.length === 0) { window.showWarningMessage(localize('no remotes to push', "Your repository has no remotes configured to push to.")); return; } - await model.push(); + await repository.push(); } @command('git.pushWithTags', { model: true }) - async pushWithTags(model: Repository): Promise { - const remotes = model.remotes; + async pushWithTags(repository: Repository): Promise { + const remotes = repository.remotes; if (remotes.length === 0) { window.showWarningMessage(localize('no remotes to push', "Your repository has no remotes configured to push to.")); return; } - await model.pushTags(); + await repository.pushTags(); window.showInformationMessage(localize('push with tags success', "Successfully pushed with tags.")); } @command('git.pushTo', { model: true }) - async pushTo(model: Repository): Promise { - const remotes = model.remotes; + async pushTo(repository: Repository): Promise { + const remotes = repository.remotes; if (remotes.length === 0) { window.showWarningMessage(localize('no remotes to push', "Your repository has no remotes configured to push to.")); return; } - if (!model.HEAD || !model.HEAD.name) { + if (!repository.HEAD || !repository.HEAD.name) { window.showWarningMessage(localize('nobranch', "Please check out a branch to push to a remote.")); return; } - const branchName = model.HEAD.name; + const branchName = repository.HEAD.name; const picks = remotes.map(r => ({ label: r.name, description: r.url })); const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName); const pick = await window.showQuickPick(picks, { placeHolder }); @@ -1072,12 +1072,12 @@ export class CommandCenter { return; } - model.pushTo(pick.label, branchName); + repository.pushTo(pick.label, branchName); } @command('git.sync', { model: true }) - async sync(model: Repository): Promise { - const HEAD = model.HEAD; + async sync(repository: Repository): Promise { + const HEAD = repository.HEAD; if (!HEAD || !HEAD.upstream) { return; @@ -1099,20 +1099,20 @@ export class CommandCenter { } } - await model.sync(); + await repository.sync(); } @command('git.publish', { model: true }) - async publish(model: Repository): Promise { - const remotes = model.remotes; + async publish(repository: Repository): Promise { + const remotes = repository.remotes; if (remotes.length === 0) { window.showWarningMessage(localize('no remotes to publish', "Your repository has no remotes configured to publish to.")); return; } - const branchName = model.HEAD && model.HEAD.name || ''; - const picks = model.remotes.map(r => r.name); + const branchName = repository.HEAD && repository.HEAD.name || ''; + const picks = repository.remotes.map(r => r.name); const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName); const choice = await window.showQuickPick(picks, { placeHolder }); @@ -1120,7 +1120,7 @@ export class CommandCenter { return; } - await model.pushTo(choice, branchName, true); + await repository.pushTo(choice, branchName, true); } @command('git.showOutput') @@ -1129,7 +1129,7 @@ export class CommandCenter { } @command('git.ignore', { model: true }) - async ignore(model: Repository, ...resourceStates: SourceControlResourceState[]): Promise { + async ignore(repository: Repository, ...resourceStates: SourceControlResourceState[]): Promise { if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) { const uri = window.activeTextEditor && window.activeTextEditor.document.uri; @@ -1137,7 +1137,7 @@ export class CommandCenter { return; } - return await model.ignore([uri]); + return await repository.ignore([uri]); } const uris = resourceStates @@ -1148,12 +1148,12 @@ export class CommandCenter { return; } - await model.ignore(uris); + await repository.ignore(uris); } @command('git.stash', { model: true }) - async stash(model: Repository): Promise { - if (model.workingTreeGroup.resources.length === 0) { + async stash(repository: Repository): Promise { + if (repository.workingTreeGroup.resourceStates.length === 0) { window.showInformationMessage(localize('no changes stash', "There are no changes to stash.")); return; } @@ -1167,12 +1167,12 @@ export class CommandCenter { return; } - await model.createStash(message); + await repository.createStash(message); } @command('git.stashPop', { model: true }) - async stashPop(model: Repository): Promise { - const stashes = await model.getStashes(); + async stashPop(repository: Repository): Promise { + const stashes = await repository.getStashes(); if (stashes.length === 0) { window.showInformationMessage(localize('no stashes', "There are no stashes to restore.")); @@ -1187,19 +1187,19 @@ export class CommandCenter { return; } - await model.popStash(choice.id); + await repository.popStash(choice.id); } @command('git.stashPopLatest', { model: true }) - async stashPopLatest(model: Repository): Promise { - const stashes = await model.getStashes(); + async stashPopLatest(repository: Repository): Promise { + const stashes = await repository.getStashes(); if (stashes.length === 0) { window.showInformationMessage(localize('no stashes', "There are no stashes to restore.")); return; } - await model.popStash(); + await repository.popStash(); } private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any { @@ -1292,8 +1292,8 @@ export class CommandCenter { return undefined; } - return repository.workingTreeGroup.resources.filter(r => r.resourceUri.toString() === uriString)[0] - || repository.indexGroup.resources.filter(r => r.resourceUri.toString() === uriString)[0]; + return repository.workingTreeGroup.resourceStates.filter(r => r.resourceUri.toString() === uriString)[0] + || repository.indexGroup.resourceStates.filter(r => r.resourceUri.toString() === uriString)[0]; } } diff --git a/extensions/git/src/contentProvider.ts b/extensions/git/src/contentProvider.ts index 1023b422c96..e8f92a82ccd 100644 --- a/extensions/git/src/contentProvider.ts +++ b/extensions/git/src/contentProvider.ts @@ -30,9 +30,9 @@ export class GitContentProvider { private cache: Cache = Object.create(null); private disposables: Disposable[] = []; - constructor(private model: Repository) { + constructor(private repository: Repository) { this.disposables.push( - model.onDidChangeRepository(this.eventuallyFireChangeEvents, this), + repository.onDidChangeRepository(this.eventuallyFireChangeEvents, this), workspace.registerTextDocumentContentProvider('git', this) ); @@ -61,12 +61,12 @@ export class GitContentProvider { if (ref === '~') { const fileUri = Uri.file(path); const uriString = fileUri.toString(); - const [indexStatus] = this.model.indexGroup.resources.filter(r => r.original.toString() === uriString); + const [indexStatus] = this.repository.indexGroup.resourceStates.filter(r => r.original.toString() === uriString); ref = indexStatus ? '' : 'HEAD'; } try { - return await this.model.show(ref, path); + return await this.repository.show(ref, path); } catch (err) { return ''; } diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index 046f7c7d205..aa0cd238b38 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -11,9 +11,7 @@ import { ExtensionContext, workspace, window, Disposable, commands, Uri } from ' import { findGit, Git, IGit } from './git'; import { Repository } from './repository'; import { Model } from './model'; -import { GitSCMProvider } from './scmProvider'; import { CommandCenter } from './commands'; -import { StatusBarCommands } from './statusbar'; import { GitContentProvider } from './contentProvider'; import { AutoFetcher } from './autofetch'; import { Askpass } from './askpass'; @@ -56,14 +54,11 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput))); const commandCenter = new CommandCenter(git, model, outputChannel, telemetryReporter); - const statusBarCommands = new StatusBarCommands(repository); - const provider = new GitSCMProvider(repository, statusBarCommands); const contentProvider = new GitContentProvider(repository); const autoFetcher = new AutoFetcher(repository); disposables.push( commandCenter, - provider, contentProvider, autoFetcher, repository diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 0e89c9e8149..b4b7d594d5a 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -5,10 +5,11 @@ 'use strict'; -import { Uri, Command, EventEmitter, Event, SourceControlResourceState, SourceControlResourceDecorations, Disposable, ProgressLocation, window, workspace, WorkspaceEdit } from 'vscode'; +import { Uri, Command, EventEmitter, Event, scm, commands, SourceControl, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, Disposable, ProgressLocation, window, workspace, WorkspaceEdit } from 'vscode'; import { Git, Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash } from './git'; import { anyEvent, eventToPromise, filterEvent, EmptyDisposable, combinedDisposable, dispose, find } from './util'; import { memoize, throttle, debounce } from './decorators'; +import { toGitUri } from './uri'; import * as path from 'path'; import * as nls from 'vscode-nls'; import * as fs from 'fs'; @@ -49,6 +50,12 @@ export enum Status { BOTH_MODIFIED } +export enum ResourceGroupType { + Merge, + Index, + WorkingTree +} + export class Resource implements SourceControlResourceState { @memoize @@ -69,7 +76,7 @@ export class Resource implements SourceControlResourceState { }; } - get resourceGroup(): ResourceGroup { return this._resourceGroup; } + get resourceGroupType(): ResourceGroupType { return this._resourceGroupType; } get type(): Status { return this._type; } get original(): Uri { return this._resourceUri; } get renameResourceUri(): Uri | undefined { return this._renameResourceUri; } @@ -149,52 +156,13 @@ export class Resource implements SourceControlResourceState { constructor( private workspaceRoot: Uri, - private _resourceGroup: ResourceGroup, + private _resourceGroupType: ResourceGroupType, private _resourceUri: Uri, private _type: Status, private _renameResourceUri?: Uri ) { } } -export abstract class ResourceGroup { - - get id(): string { return this._id; } - get contextKey(): string { return this._id; } - get label(): string { return this._label; } - get resources(): Resource[] { return this._resources; } - - constructor(private _id: string, private _label: string, private _resources: Resource[]) { - - } -} - -export class MergeGroup extends ResourceGroup { - - static readonly ID = 'merge'; - - constructor(resources: Resource[] = []) { - super(MergeGroup.ID, localize('merge changes', "Merge Changes"), resources); - } -} - -export class IndexGroup extends ResourceGroup { - - static readonly ID = 'index'; - - constructor(resources: Resource[] = []) { - super(IndexGroup.ID, localize('staged changes', "Staged Changes"), resources); - } -} - -export class WorkingTreeGroup extends ResourceGroup { - - static readonly ID = 'workingTree'; - - constructor(resources: Resource[] = []) { - super(WorkingTreeGroup.ID, localize('changes', "Changes"), resources); - } -} - export enum Operation { Status = 1 << 0, Add = 1 << 1, @@ -302,6 +270,10 @@ export interface IRepository { clean(resources: Uri[]): Promise; } +export interface GitResourceGroup extends SourceControlResourceGroup { + resourceStates: Resource[]; +} + export class Repository implements IRepository, Disposable { private _onDidChangeRepository = new EventEmitter(); @@ -310,12 +282,9 @@ export class Repository implements IRepository, Disposable { private _onDidChangeState = new EventEmitter(); readonly onDidChangeState: Event = this._onDidChangeState.event; - private _onDidChangeResources = new EventEmitter(); - readonly onDidChangeResources: Event = this._onDidChangeResources.event; - @memoize get onDidChange(): Event { - return anyEvent(this.onDidChangeState, this.onDidChangeResources); + return anyEvent(this.onDidChangeState); } private _onRunOperation = new EventEmitter(); @@ -329,14 +298,17 @@ export class Repository implements IRepository, Disposable { return anyEvent(this.onRunOperation as Event, this.onDidRunOperation as Event); } - private _mergeGroup = new MergeGroup([]); - get mergeGroup(): MergeGroup { return this._mergeGroup; } + private _sourceControl: SourceControl; + get sourceControl(): SourceControl { return this._sourceControl; } - private _indexGroup = new IndexGroup([]); - get indexGroup(): IndexGroup { return this._indexGroup; } + private _mergeGroup: SourceControlResourceGroup; + get mergeGroup(): GitResourceGroup { return this._mergeGroup as GitResourceGroup; } - private _workingTreeGroup = new WorkingTreeGroup([]); - get workingTreeGroup(): WorkingTreeGroup { return this._workingTreeGroup; } + private _indexGroup: SourceControlResourceGroup; + get indexGroup(): GitResourceGroup { return this._indexGroup as GitResourceGroup; } + + private _workingTreeGroup: SourceControlResourceGroup; + get workingTreeGroup(): GitResourceGroup { return this._workingTreeGroup as GitResourceGroup; } private _HEAD: Branch | undefined; get HEAD(): Branch | undefined { @@ -367,10 +339,11 @@ export class Repository implements IRepository, Disposable { this._HEAD = undefined; this._refs = []; this._remotes = []; - this._mergeGroup = new MergeGroup(); - this._indexGroup = new IndexGroup(); - this._workingTreeGroup = new WorkingTreeGroup(); - this._onDidChangeResources.fire(); + this.mergeGroup.resourceStates = []; + this.indexGroup.resourceStates = []; + this.workingTreeGroup.resourceStates = []; + this._sourceControl.count = 0; + commands.executeCommand('setContext', 'gitState', ''); } private onWorkspaceChange: Event; @@ -387,9 +360,43 @@ export class Repository implements IRepository, Disposable { this.onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete); this.disposables.push(fsWatcher); + this._sourceControl = scm.createSourceControl('git', 'Git'); + this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit") }; + this._sourceControl.quickDiffProvider = this; + this.disposables.push(this._sourceControl); + + this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "Merge Changes")); + this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "Staged Changes")); + this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "Changes")); + + this.mergeGroup.hideWhenEmpty = true; + this.indexGroup.hideWhenEmpty = true; + + this.disposables.push(this.mergeGroup); + this.disposables.push(this.indexGroup); + this.disposables.push(this.workingTreeGroup); + + this.updateCommitTemplate(); this.status(); } + // TODO@Joao reorganize this + provideOriginalResource(uri: Uri): Uri | undefined { + if (uri.scheme !== 'file') { + return; + } + + return toGitUri(uri, '', true); + } + + private async updateCommitTemplate(): Promise { + try { + this._sourceControl.commitTemplate = await this.repository.getCommitTemplate(); + } catch (e) { + // noop + } + } + @throttle async init(): Promise { if (this.state !== State.NotAGitRepository) { @@ -435,7 +442,7 @@ export class Repository implements IRepository, Disposable { resources.forEach(r => { const raw = r.toString(); - const scmResource = find(this.workingTreeGroup.resources, sr => sr.resourceUri.toString() === raw); + const scmResource = find(this.workingTreeGroup.resourceStates, sr => sr.resourceUri.toString() === raw); if (!scmResource) { return; @@ -731,37 +738,59 @@ export class Repository implements IRepository, Disposable { const renameUri = raw.rename ? Uri.file(path.join(this.repository.root, raw.rename)) : undefined; switch (raw.x + raw.y) { - case '??': return workingTree.push(new Resource(this.workspaceRoot, this.workingTreeGroup, uri, Status.UNTRACKED)); - case '!!': return workingTree.push(new Resource(this.workspaceRoot, this.workingTreeGroup, uri, Status.IGNORED)); - case 'DD': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.BOTH_DELETED)); - case 'AU': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.ADDED_BY_US)); - case 'UD': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.DELETED_BY_THEM)); - case 'UA': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.ADDED_BY_THEM)); - case 'DU': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.DELETED_BY_US)); - case 'AA': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.BOTH_ADDED)); - case 'UU': return merge.push(new Resource(this.workspaceRoot, this.mergeGroup, uri, Status.BOTH_MODIFIED)); + case '??': return workingTree.push(new Resource(this.workspaceRoot, ResourceGroupType.WorkingTree, uri, Status.UNTRACKED)); + case '!!': return workingTree.push(new Resource(this.workspaceRoot, ResourceGroupType.WorkingTree, uri, Status.IGNORED)); + case 'DD': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.BOTH_DELETED)); + case 'AU': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.ADDED_BY_US)); + case 'UD': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.DELETED_BY_THEM)); + case 'UA': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.ADDED_BY_THEM)); + case 'DU': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.DELETED_BY_US)); + case 'AA': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.BOTH_ADDED)); + case 'UU': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.BOTH_MODIFIED)); } let isModifiedInIndex = false; switch (raw.x) { - case 'M': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_MODIFIED)); isModifiedInIndex = true; break; - case 'A': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_ADDED)); break; - case 'D': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_DELETED)); break; - case 'R': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_RENAMED, renameUri)); break; - case 'C': index.push(new Resource(this.workspaceRoot, this.indexGroup, uri, Status.INDEX_COPIED, renameUri)); break; + case 'M': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_MODIFIED)); isModifiedInIndex = true; break; + case 'A': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_ADDED)); break; + case 'D': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_DELETED)); break; + case 'R': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_RENAMED, renameUri)); break; + case 'C': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_COPIED, renameUri)); break; } switch (raw.y) { - case 'M': workingTree.push(new Resource(this.workspaceRoot, this.workingTreeGroup, uri, Status.MODIFIED, renameUri)); break; - case 'D': workingTree.push(new Resource(this.workspaceRoot, this.workingTreeGroup, uri, Status.DELETED, renameUri)); break; + case 'M': workingTree.push(new Resource(this.workspaceRoot, ResourceGroupType.WorkingTree, uri, Status.MODIFIED, renameUri)); break; + case 'D': workingTree.push(new Resource(this.workspaceRoot, ResourceGroupType.WorkingTree, uri, Status.DELETED, renameUri)); break; } }); - this._mergeGroup = new MergeGroup(merge); - this._indexGroup = new IndexGroup(index); - this._workingTreeGroup = new WorkingTreeGroup(workingTree); - this._onDidChangeResources.fire(); + // set resource groups + this.mergeGroup.resourceStates = merge; + this.indexGroup.resourceStates = index; + this.workingTreeGroup.resourceStates = workingTree; + + // set count badge + const countBadge = workspace.getConfiguration('git').get('countBadge'); + let count = merge.length + index.length + workingTree.length; + + switch (countBadge) { + case 'off': count = 0; break; + case 'tracked': count = count - workingTree.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED).length; break; + } + + this._sourceControl.count = count; + + // set context key + let stateContextKey = ''; + + switch (this.state) { + case State.Uninitialized: stateContextKey = 'uninitialized'; break; + case State.Idle: stateContextKey = 'idle'; break; + case State.NotAGitRepository: stateContextKey = 'norepo'; break; + } + + commands.executeCommand('setContext', 'gitState', stateContextKey); } private onFSChange(uri: Uri): void { diff --git a/extensions/git/src/scmProvider.ts b/extensions/git/src/scmProvider.ts deleted file mode 100644 index 2b8ccc8465b..00000000000 --- a/extensions/git/src/scmProvider.ts +++ /dev/null @@ -1,120 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -import { scm, Uri, Disposable, SourceControl, SourceControlResourceGroup, Event, workspace, commands } from 'vscode'; -import { Repository, State, Status } from './repository'; -import { StatusBarCommands } from './statusbar'; -import { mapEvent } from './util'; -import { toGitUri } from './uri'; -import * as nls from 'vscode-nls'; - -const localize = nls.loadMessageBundle(); - -export class GitSCMProvider { - - private disposables: Disposable[] = []; - get contextKey(): string { return 'git'; } - - get onDidChange(): Event { - return mapEvent(this.model.onDidChange, () => this); - } - - get label(): string { return 'Git'; } - - get stateContextKey(): string { - switch (this.model.state) { - case State.Uninitialized: return 'uninitialized'; - case State.Idle: return 'idle'; - case State.NotAGitRepository: return 'norepo'; - default: return ''; - } - } - - get count(): number { - const countBadge = workspace.getConfiguration('git').get('countBadge'); - const total = this.model.mergeGroup.resources.length - + this.model.indexGroup.resources.length - + this.model.workingTreeGroup.resources.length; - - switch (countBadge) { - case 'off': return 0; - case 'tracked': return total - this.model.workingTreeGroup.resources.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED).length; - default: return total; - } - } - - private _sourceControl: SourceControl; - - get sourceControl(): SourceControl { - return this._sourceControl; - } - - private mergeGroup: SourceControlResourceGroup; - private indexGroup: SourceControlResourceGroup; - private workingTreeGroup: SourceControlResourceGroup; - - constructor( - private model: Repository, - private statusBarCommands: StatusBarCommands - ) { - this._sourceControl = scm.createSourceControl('git', 'Git'); - this.disposables.push(this._sourceControl); - - this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit") }; - this._sourceControl.quickDiffProvider = this; - - this.statusBarCommands.onDidChange(this.onDidStatusBarCommandsChange, this, this.disposables); - this.onDidStatusBarCommandsChange(); - - this.mergeGroup = this._sourceControl.createResourceGroup(model.mergeGroup.id, model.mergeGroup.label); - this.indexGroup = this._sourceControl.createResourceGroup(model.indexGroup.id, model.indexGroup.label); - this.workingTreeGroup = this._sourceControl.createResourceGroup(model.workingTreeGroup.id, model.workingTreeGroup.label); - - this.mergeGroup.hideWhenEmpty = true; - this.indexGroup.hideWhenEmpty = true; - - this.disposables.push(this.mergeGroup); - this.disposables.push(this.indexGroup); - this.disposables.push(this.workingTreeGroup); - - model.onDidChange(this.onDidModelChange, this, this.disposables); - this.updateCommitTemplate(); - } - - private async updateCommitTemplate(): Promise { - try { - this._sourceControl.commitTemplate = await this.model.getCommitTemplate(); - } catch (e) { - // noop - } - } - - provideOriginalResource(uri: Uri): Uri | undefined { - if (uri.scheme !== 'file') { - return; - } - - return toGitUri(uri, '', true); - } - - private onDidModelChange(): void { - this.mergeGroup.resourceStates = this.model.mergeGroup.resources; - this.indexGroup.resourceStates = this.model.indexGroup.resources; - this.workingTreeGroup.resourceStates = this.model.workingTreeGroup.resources; - this._sourceControl.count = this.count; - commands.executeCommand('setContext', 'gitState', this.stateContextKey); - } - - private onDidStatusBarCommandsChange(): void { - this._sourceControl.statusBarCommands = this.statusBarCommands.commands; - } - - dispose(): void { - this.disposables.forEach(d => d.dispose()); - this.disposables = []; - } -} \ No newline at end of file diff --git a/extensions/git/src/statusbar.ts b/extensions/git/src/statusbar.ts index bf88320a8d6..73b2951f902 100644 --- a/extensions/git/src/statusbar.ts +++ b/extensions/git/src/statusbar.ts @@ -19,25 +19,25 @@ class CheckoutStatusBar { get onDidChange(): Event { return this._onDidChange.event; } private disposables: Disposable[] = []; - constructor(private model: Repository) { - model.onDidChange(this._onDidChange.fire, this._onDidChange, this.disposables); + constructor(private repository: Repository) { + repository.onDidChange(this._onDidChange.fire, this._onDidChange, this.disposables); } get command(): Command | undefined { - const HEAD = this.model.HEAD; + const HEAD = this.repository.HEAD; if (!HEAD) { return undefined; } - const tag = this.model.refs.filter(iref => iref.type === RefType.Tag && iref.commit === HEAD.commit)[0]; + const tag = this.repository.refs.filter(iref => iref.type === RefType.Tag && iref.commit === HEAD.commit)[0]; const tagName = tag && tag.name; const head = HEAD.name || tagName || (HEAD.commit || '').substr(0, 8); const title = '$(git-branch) ' + head - + (this.model.workingTreeGroup.resources.length > 0 ? '*' : '') - + (this.model.indexGroup.resources.length > 0 ? '+' : '') - + (this.model.mergeGroup.resources.length > 0 ? '!' : ''); + + (this.repository.workingTreeGroup.resourceStates.length > 0 ? '*' : '') + + (this.repository.indexGroup.resourceStates.length > 0 ? '+' : '') + + (this.repository.mergeGroup.resourceStates.length > 0 ? '!' : ''); return { command: 'git.checkout', @@ -76,24 +76,24 @@ class SyncStatusBar { this._onDidChange.fire(); } - constructor(private model: Repository) { - model.onDidChange(this.onModelChange, this, this.disposables); - model.onDidChangeOperations(this.onOperationsChange, this, this.disposables); + constructor(private repository: Repository) { + repository.onDidChange(this.onModelChange, this, this.disposables); + repository.onDidChangeOperations(this.onOperationsChange, this, this.disposables); this._onDidChange.fire(); } private onOperationsChange(): void { this.state = { ...this.state, - isSyncRunning: this.model.operations.isRunning(Operation.Sync) + isSyncRunning: this.repository.operations.isRunning(Operation.Sync) }; } private onModelChange(): void { this.state = { ...this.state, - hasRemotes: this.model.remotes.length > 0, - HEAD: this.model.HEAD + hasRemotes: this.repository.remotes.length > 0, + HEAD: this.repository.HEAD }; } @@ -149,9 +149,9 @@ export class StatusBarCommands { private checkoutStatusBar: CheckoutStatusBar; private disposables: Disposable[] = []; - constructor(model: Repository) { - this.syncStatusBar = new SyncStatusBar(model); - this.checkoutStatusBar = new CheckoutStatusBar(model); + constructor(repository: Repository) { + this.syncStatusBar = new SyncStatusBar(repository); + this.checkoutStatusBar = new CheckoutStatusBar(repository); } get onDidChange(): Event {