Browse Source

Reworks container usage

main
Eric Amodio 3 years ago
parent
commit
5dee2e97b0
165 changed files with 1401 additions and 1105 deletions
  1. +4
    -4
      src/annotations/annotations.ts
  2. +2
    -2
      src/annotations/autolinks.ts
  3. +12
    -11
      src/annotations/blameAnnotationProvider.ts
  4. +21
    -15
      src/annotations/fileAnnotationController.ts
  5. +7
    -7
      src/annotations/gutterBlameAnnotationProvider.ts
  6. +18
    -14
      src/annotations/gutterChangesAnnotationProvider.ts
  7. +4
    -3
      src/annotations/gutterHeatmapBlameAnnotationProvider.ts
  8. +22
    -18
      src/annotations/lineAnnotationController.ts
  9. +5
    -5
      src/api/actionRunners.ts
  10. +7
    -2
      src/api/api.ts
  11. +6
    -6
      src/avatars.ts
  12. +14
    -8
      src/codelens/codeLensController.ts
  13. +24
    -29
      src/codelens/codeLensProvider.ts
  14. +1
    -1
      src/commands/addAuthors.ts
  15. +1
    -1
      src/commands/browseRepoAtRevision.ts
  16. +1
    -1
      src/commands/closeUnchangedFiles.ts
  17. +1
    -1
      src/commands/closeView.ts
  18. +2
    -2
      src/commands/common.ts
  19. +2
    -2
      src/commands/compareWith.ts
  20. +1
    -1
      src/commands/copyCurrentBranch.ts
  21. +9
    -5
      src/commands/copyMessageToClipboard.ts
  22. +9
    -5
      src/commands/copyShaToClipboard.ts
  23. +1
    -1
      src/commands/createPullRequestOnRemote.ts
  24. +1
    -1
      src/commands/diffLineWithPrevious.ts
  25. +3
    -3
      src/commands/diffLineWithWorking.ts
  26. +9
    -5
      src/commands/diffWith.ts
  27. +1
    -1
      src/commands/diffWithNext.ts
  28. +1
    -1
      src/commands/diffWithPrevious.ts
  29. +2
    -2
      src/commands/diffWithRevision.ts
  30. +1
    -1
      src/commands/diffWithRevisionFrom.ts
  31. +8
    -3
      src/commands/diffWithWorking.ts
  32. +8
    -6
      src/commands/externalDiff.ts
  33. +1
    -1
      src/commands/git/branch.ts
  34. +2
    -2
      src/commands/git/cherry-pick.ts
  35. +2
    -2
      src/commands/git/coauthors.ts
  36. +2
    -2
      src/commands/git/fetch.ts
  37. +4
    -4
      src/commands/git/log.ts
  38. +3
    -3
      src/commands/git/merge.ts
  39. +2
    -2
      src/commands/git/pull.ts
  40. +3
    -3
      src/commands/git/push.ts
  41. +4
    -4
      src/commands/git/rebase.ts
  42. +2
    -2
      src/commands/git/reset.ts
  43. +2
    -2
      src/commands/git/revert.ts
  44. +5
    -5
      src/commands/git/search.ts
  45. +5
    -2
      src/commands/git/show.ts
  46. +5
    -5
      src/commands/git/stash.ts
  47. +1
    -1
      src/commands/git/status.ts
  48. +2
    -2
      src/commands/git/switch.ts
  49. +1
    -1
      src/commands/git/tag.ts
  50. +35
    -31
      src/commands/gitCommands.actions.ts
  51. +6
    -6
      src/commands/gitCommands.ts
  52. +2
    -2
      src/commands/inviteToLiveShare.ts
  53. +1
    -1
      src/commands/openAssociatedPullRequestOnRemote.ts
  54. +1
    -1
      src/commands/openChangedFiles.ts
  55. +2
    -2
      src/commands/openCommitOnRemote.ts
  56. +5
    -3
      src/commands/openFileAtRevision.ts
  57. +2
    -2
      src/commands/openFileFromRemote.ts
  58. +9
    -5
      src/commands/openFileOnRemote.ts
  59. +2
    -2
      src/commands/openOnRemote.ts
  60. +2
    -2
      src/commands/openPullRequestOnRemote.ts
  61. +1
    -1
      src/commands/openRevisionFile.ts
  62. +4
    -2
      src/commands/openWorkingFile.ts
  63. +8
    -6
      src/commands/quickCommand.buttons.ts
  64. +52
    -26
      src/commands/quickCommand.steps.ts
  65. +1
    -1
      src/commands/quickCommand.ts
  66. +2
    -2
      src/commands/rebaseEditor.ts
  67. +7
    -7
      src/commands/remoteProviders.ts
  68. +12
    -3
      src/commands/repositories.ts
  69. +1
    -1
      src/commands/searchCommits.ts
  70. +2
    -2
      src/commands/showCommitsInView.ts
  71. +1
    -1
      src/commands/showQuickBranchHistory.ts
  72. +2
    -2
      src/commands/showQuickCommit.ts
  73. +5
    -3
      src/commands/showQuickCommitFile.ts
  74. +1
    -1
      src/commands/showQuickFileHistory.ts
  75. +11
    -11
      src/commands/showView.ts
  76. +4
    -4
      src/commands/stashSave.ts
  77. +16
    -8
      src/commands/switchMode.ts
  78. +1
    -1
      src/commands/toggleCodeLens.ts
  79. +2
    -2
      src/commands/toggleFileAnnotations.ts
  80. +1
    -1
      src/commands/toggleLineBlame.ts
  81. +155
    -118
      src/container.ts
  82. +33
    -37
      src/extension.ts
  83. +22
    -15
      src/git/formatters/commitFormatter.ts
  84. +4
    -4
      src/git/fsProvider.ts
  85. +7
    -3
      src/git/git.ts
  86. +72
    -77
      src/git/gitService.ts
  87. +5
    -5
      src/git/gitUri.ts
  88. +6
    -6
      src/git/models/branch.ts
  89. +4
    -4
      src/git/models/commit.ts
  90. +1
    -1
      src/git/models/models.ts
  91. +7
    -4
      src/git/models/remote.ts
  92. +36
    -30
      src/git/models/repository.ts
  93. +1
    -1
      src/git/models/stashCommit.ts
  94. +1
    -1
      src/git/models/status.ts
  95. +6
    -6
      src/git/remotes/github.ts
  96. +8
    -8
      src/git/remotes/provider.ts
  97. +12
    -12
      src/hovers/hovers.ts
  98. +34
    -28
      src/hovers/lineHoverController.ts
  99. +27
    -23
      src/partners.ts
  100. +1
    -1
      src/quickpicks/commitPicker.ts

+ 4
- 4
src/annotations/annotations.ts View File

@ -63,14 +63,14 @@ export async function getHeatmapColors() {
if (heatmapColors == null) {
let colors;
if (
Container.config.heatmap.coldColor === defaultHeatmapColdColor &&
Container.config.heatmap.hotColor === defaultHeatmapHotColor
Container.instance.config.heatmap.coldColor === defaultHeatmapColdColor &&
Container.instance.config.heatmap.hotColor === defaultHeatmapHotColor
) {
colors = defaultHeatmapColors;
} else {
const chroma = (await import(/* webpackChunkName: "heatmap-chroma" */ 'chroma-js')).default;
colors = chroma
.scale([Container.config.heatmap.hotColor, Container.config.heatmap.coldColor])
.scale([Container.instance.config.heatmap.hotColor, Container.instance.config.heatmap.coldColor])
.mode('lrgb')
.classes(20)
.colors(20);
@ -110,7 +110,7 @@ export class Annotations {
) {
const [r, g, b, a] = this.getHeatmapColor(date, heatmap);
const { locations } = Container.config.heatmap;
const { locations } = Container.instance.config.heatmap;
const gutter = locations.includes(HeatmapLocations.Gutter);
const overview = locations.includes(HeatmapLocations.Overview);

+ 2
- 2
src/annotations/autolinks.ts View File

@ -31,7 +31,7 @@ export class Autolinks implements Disposable {
protected _disposable: Disposable | undefined;
private _references: CacheableAutolinkReference[] = [];
constructor() {
constructor(private readonly container: Container) {
this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this));
this.onConfigurationChanged();
@ -43,7 +43,7 @@ export class Autolinks implements Disposable {
private onConfigurationChanged(e?: ConfigurationChangeEvent) {
if (configuration.changed(e, 'autolinks')) {
this._references = Container.config.autolinks ?? [];
this._references = this.container.config.autolinks ?? [];
}
}

+ 12
- 11
src/annotations/blameAnnotationProvider.ts View File

@ -18,12 +18,13 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
annotationType: FileAnnotationType,
editor: TextEditor,
trackedDocument: TrackedDocument<GitDocumentState>,
protected readonly container: Container,
) {
super(annotationType, editor, trackedDocument);
this.blame = editor.document.isDirty
? Container.git.getBlameForFileContents(this.trackedDocument.uri, editor.document.getText())
: Container.git.getBlameForFile(this.trackedDocument.uri);
? this.container.git.getBlameForFileContents(this.trackedDocument.uri, editor.document.getText())
: this.container.git.getBlameForFile(this.trackedDocument.uri);
if (editor.document.isDirty) {
trackedDocument.setForceDirtyStateChangeOnNextDocumentChange();
@ -69,7 +70,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
dates.sort((a, b) => a.getTime() - b.getTime());
const coldThresholdDate = new Date();
coldThresholdDate.setDate(coldThresholdDate.getDate() - (Container.config.heatmap.ageThreshold || 90));
coldThresholdDate.setDate(coldThresholdDate.getDate() - (this.container.config.heatmap.ageThreshold || 90));
const coldThresholdTimestamp = coldThresholdDate.getTime();
const hotDates: Date[] = [];
@ -122,8 +123,8 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
registerHoverProviders(providers: { details: boolean; changes: boolean }) {
if (
!Container.config.hovers.enabled ||
!Container.config.hovers.annotations.enabled ||
!this.container.config.hovers.enabled ||
!this.container.config.hovers.annotations.enabled ||
(!providers.details && !providers.changes)
) {
return;
@ -144,7 +145,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
position: Position,
_token: CancellationToken,
): Promise<Hover | undefined> {
if (Container.config.hovers.annotations.over !== 'line' && position.character !== 0) return undefined;
if (this.container.config.hovers.annotations.over !== 'line' && position.character !== 0) return undefined;
if (this.document.uri.toString() !== document.uri.toString()) return undefined;
@ -175,7 +176,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
// Get the full commit message -- since blame only returns the summary
let logCommit: GitCommit | undefined = undefined;
if (!commit.isUncommitted) {
logCommit = await Container.git.getCommitForFile(commit.repoPath, commit.uri.fsPath, {
logCommit = await this.container.git.getCommitForFile(commit.repoPath, commit.uri.fsPath, {
ref: commit.sha,
});
if (logCommit != null) {
@ -194,12 +195,12 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
logCommit ?? commit,
await GitUri.fromUri(document.uri),
editorLine,
Container.config.hovers.detailsMarkdownFormat,
Container.config.defaultDateFormat,
this.container.config.hovers.detailsMarkdownFormat,
this.container.config.defaultDateFormat,
{
autolinks: Container.config.hovers.autolinks.enabled,
autolinks: this.container.config.hovers.autolinks.enabled,
pullRequests: {
enabled: Container.config.hovers.pullRequests.enabled,
enabled: this.container.config.hovers.pullRequests.enabled,
},
},
);

+ 21
- 15
src/annotations/fileAnnotationController.ts View File

@ -79,11 +79,13 @@ export class FileAnnotationController implements Disposable {
private readonly _toggleModes: Map<FileAnnotationType, AnnotationsToggleMode>;
private _windowAnnotationType?: FileAnnotationType | undefined = undefined;
constructor() {
this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this));
constructor(private readonly container: Container) {
this._disposable = Disposable.from(
container.onReady(this.onReady, this),
configuration.onDidChange(this.onConfigurationChanged, this),
);
this._toggleModes = new Map<FileAnnotationType, AnnotationsToggleMode>();
this.onConfigurationChanged();
}
dispose() {
@ -99,8 +101,12 @@ export class FileAnnotationController implements Disposable {
this._disposable?.dispose();
}
private onReady(): void {
this.onConfigurationChanged();
}
private onConfigurationChanged(e?: ConfigurationChangeEvent) {
const cfg = Container.config;
const cfg = this.container.config;
if (configuration.changed(e, 'blame.highlight')) {
Decorations.gutterBlameHighlight?.dispose();
@ -274,7 +280,7 @@ export class FileAnnotationController implements Disposable {
}
private onTextDocumentClosed(document: TextDocument) {
if (!Container.git.isTrackable(document.uri)) return;
if (!this.container.git.isTrackable(document.uri)) return;
for (const [key, p] of this._annotationProviders) {
if (p.document !== document) continue;
@ -340,7 +346,7 @@ export class FileAnnotationController implements Disposable {
const provider = this.getProvider(editor);
if (provider == null) return undefined;
const trackedDocument = await Container.tracker.get(editor!.document);
const trackedDocument = await this.container.tracker.get(editor!.document);
if (trackedDocument == null || !trackedDocument.isBlameable) return undefined;
return provider.annotationType;
@ -385,7 +391,7 @@ export class FileAnnotationController implements Disposable {
if (editor == null) return false; // || editor.viewColumn == null) return false;
this._editor = editor;
const trackedDocument = await Container.tracker.getOrAdd(editor.document);
const trackedDocument = await this.container.tracker.getOrAdd(editor.document);
if (!trackedDocument.isBlameable) return false;
const currentProvider = this.getProvider(editor);
@ -433,7 +439,7 @@ export class FileAnnotationController implements Disposable {
on?: boolean,
): Promise<boolean> {
if (editor != null) {
const trackedDocument = await Container.tracker.getOrAdd(editor.document);
const trackedDocument = await this.container.tracker.getOrAdd(editor.document);
if ((type === FileAnnotationType.Changes && !trackedDocument.isTracked) || !trackedDocument.isBlameable) {
return false;
}
@ -459,7 +465,7 @@ export class FileAnnotationController implements Disposable {
private async attachKeyboardHook() {
// Allows pressing escape to exit the annotations
if (this._keyboardScope == null) {
this._keyboardScope = await Container.keyboard.beginScope({
this._keyboardScope = await this.container.keyboard.beginScope({
escape: {
onDidPressKey: async () => {
const e = this._editor;
@ -535,20 +541,20 @@ export class FileAnnotationController implements Disposable {
// Allows pressing escape to exit the annotations
await this.attachKeyboardHook();
const trackedDocument = await Container.tracker.getOrAdd(editor.document);
const trackedDocument = await this.container.tracker.getOrAdd(editor.document);
let provider: AnnotationProviderBase | undefined = undefined;
switch (type) {
case FileAnnotationType.Blame:
provider = new GutterBlameAnnotationProvider(editor, trackedDocument);
provider = new GutterBlameAnnotationProvider(editor, trackedDocument, this.container);
break;
case FileAnnotationType.Changes:
provider = new GutterChangesAnnotationProvider(editor, trackedDocument);
provider = new GutterChangesAnnotationProvider(editor, trackedDocument, this.container);
break;
case FileAnnotationType.Heatmap:
provider = new GutterHeatmapBlameAnnotationProvider(editor, trackedDocument);
provider = new GutterHeatmapBlameAnnotationProvider(editor, trackedDocument, this.container);
break;
}
if (provider == null || !(await provider.validate())) return undefined;
@ -565,8 +571,8 @@ export class FileAnnotationController implements Disposable {
window.onDidChangeTextEditorViewColumn(this.onTextEditorViewColumnChanged, this),
window.onDidChangeVisibleTextEditors(Functions.debounce(this.onVisibleTextEditorsChanged, 50), this),
workspace.onDidCloseTextDocument(this.onTextDocumentClosed, this),
Container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this),
Container.tracker.onDidChangeDirtyState(this.onDirtyStateChanged, this),
this.container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this),
this.container.tracker.onDidChangeDirtyState(this.onDirtyStateChanged, this),
);
}

+ 7
- 7
src/annotations/gutterBlameAnnotationProvider.ts View File

@ -14,8 +14,8 @@ import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
import { Decorations } from './fileAnnotationController';
export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
constructor(editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
super(FileAnnotationType.Blame, editor, trackedDocument);
constructor(editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>, container: Container) {
super(FileAnnotationType.Blame, editor, trackedDocument, container);
}
override clear() {
@ -39,7 +39,7 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
let start = process.hrtime();
const cfg = Container.config.blame;
const cfg = this.container.config.blame;
// Precalculate the formatting options so we don't need to do it on each iteration
const tokenOptions = Strings.getTokensFromTemplate(cfg.format).reduce<{
@ -51,17 +51,17 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
let getBranchAndTagTips;
if (CommitFormatter.has(cfg.format, 'tips')) {
getBranchAndTagTips = await Container.git.getBranchesAndTagsTipsFn(blame.repoPath);
getBranchAndTagTips = await this.container.git.getBranchesAndTagsTipsFn(blame.repoPath);
}
const options: CommitFormatOptions = {
dateFormat: cfg.dateFormat === null ? Container.config.defaultDateFormat : cfg.dateFormat,
dateFormat: cfg.dateFormat === null ? this.container.config.defaultDateFormat : cfg.dateFormat,
getBranchAndTagTips: getBranchAndTagTips,
tokenOptions: tokenOptions,
};
const avatars = cfg.avatars;
const gravatarDefault = Container.config.defaultGravatarsStyle;
const gravatarDefault = this.container.config.defaultGravatarsStyle;
const separateLines = cfg.separateLines;
const renderOptions = Annotations.gutterRenderOptions(
separateLines,
@ -169,7 +169,7 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
Logger.log(cc, `${Strings.getDurationMilliseconds(start)} ms to apply all gutter blame annotations`);
}
this.registerHoverProviders(Container.config.hovers.annotations);
this.registerHoverProviders(this.container.config.hovers.annotations);
return true;
}

+ 18
- 14
src/annotations/gutterChangesAnnotationProvider.ts View File

@ -32,7 +32,11 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase
private state: { commit: GitLogCommit | undefined; diffs: GitDiff[] } | undefined;
private hoverProviderDisposable: Disposable | undefined;
constructor(editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
constructor(
editor: TextEditor,
trackedDocument: TrackedDocument<GitDocumentState>,
private readonly container: Container,
) {
super(FileAnnotationType.Changes, editor, trackedDocument);
}
@ -74,13 +78,13 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase
let localChanges = ref1 == null && ref2 == null;
if (localChanges) {
let ref = await Container.git.getOldestUnpushedRefForFile(
let ref = await this.container.git.getOldestUnpushedRefForFile(
this.trackedDocument.uri.repoPath!,
this.trackedDocument.uri.fsPath,
);
if (ref != null) {
ref = `${ref}^`;
commit = await Container.git.getCommitForFile(
commit = await this.container.git.getCommitForFile(
this.trackedDocument.uri.repoPath,
this.trackedDocument.uri.fsPath,
{ ref: ref },
@ -96,15 +100,15 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase
localChanges = false;
}
} else {
const status = await Container.git.getStatusForFile(
const status = await this.container.git.getStatusForFile(
this.trackedDocument.uri.repoPath!,
this.trackedDocument.uri.fsPath,
);
const commits = status?.toPsuedoCommits(
await Container.git.getCurrentUser(this.trackedDocument.uri.repoPath!),
await this.container.git.getCurrentUser(this.trackedDocument.uri.repoPath!),
);
if (commits?.length) {
commit = await Container.git.getCommitForFile(
commit = await this.container.git.getCommitForFile(
this.trackedDocument.uri.repoPath,
this.trackedDocument.uri.fsPath,
);
@ -118,7 +122,7 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase
}
if (!localChanges) {
commit = await Container.git.getCommitForFile(
commit = await this.container.git.getCommitForFile(
this.trackedDocument.uri.repoPath,
this.trackedDocument.uri.fsPath,
{
@ -139,14 +143,14 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase
await Promise.all(
ref2 == null && this.editor.document.isDirty
? [
Container.git.getDiffForFileContents(
this.container.git.getDiffForFileContents(
this.trackedDocument.uri,
ref1!,
this.editor.document.getText(),
),
Container.git.getDiffForFile(this.trackedDocument.uri, ref1, ref2),
this.container.git.getDiffForFile(this.trackedDocument.uri, ref1, ref2),
]
: [Container.git.getDiffForFile(this.trackedDocument.uri, ref1, ref2)],
: [this.container.git.getDiffForFile(this.trackedDocument.uri, ref1, ref2)],
)
).filter(<T>(d?: T): d is T => Boolean(d));
if (!diffs?.length) return false;
@ -162,11 +166,11 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase
const blame =
context?.sha != null && context?.only
? this.editor?.document.isDirty
? await Container.git.getBlameForFileContents(
? await this.container.git.getBlameForFileContents(
this.trackedDocument.uri,
this.editor.document.getText(),
)
: await Container.git.getBlameForFile(this.trackedDocument.uri)
: await this.container.git.getBlameForFile(this.trackedDocument.uri)
: undefined;
let selection: Selection | undefined;
@ -279,7 +283,7 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase
}
registerHoverProvider() {
if (!Container.config.hovers.enabled || !Container.config.hovers.annotations.enabled) {
if (!this.container.config.hovers.enabled || !this.container.config.hovers.annotations.enabled) {
return;
}
@ -294,7 +298,7 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase
provideHover(document: TextDocument, position: Position, _token: CancellationToken): Hover | undefined {
if (this.state == null) return undefined;
if (Container.config.hovers.annotations.over !== 'line' && position.character !== 0) return undefined;
if (this.container.config.hovers.annotations.over !== 'line' && position.character !== 0) return undefined;
const { commit, diffs } = this.state;

+ 4
- 3
src/annotations/gutterHeatmapBlameAnnotationProvider.ts View File

@ -1,6 +1,7 @@
'use strict';
import { Range, TextEditor, TextEditorDecorationType } from 'vscode';
import { FileAnnotationType } from '../configuration';
import { Container } from '../container';
import { GitBlameCommit } from '../git/git';
import { Logger } from '../logger';
import { log, Strings } from '../system';
@ -11,8 +12,8 @@ import { Annotations } from './annotations';
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
export class GutterHeatmapBlameAnnotationProvider extends BlameAnnotationProviderBase {
constructor(editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
super(FileAnnotationType.Heatmap, editor, trackedDocument);
constructor(editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>, container: Container) {
super(FileAnnotationType.Heatmap, editor, trackedDocument, container);
}
@log()
@ -58,7 +59,7 @@ export class GutterHeatmapBlameAnnotationProvider extends BlameAnnotationProvide
Logger.log(cc, `${Strings.getDurationMilliseconds(start)} ms to apply recent changes annotations`);
}
// this.registerHoverProviders(Container.config.hovers.annotations);
// this.registerHoverProviders(this.container.config.hovers.annotations);
return true;
}

+ 22
- 18
src/annotations/lineAnnotationController.ts View File

@ -34,27 +34,31 @@ export class LineAnnotationController implements Disposable {
private _editor: TextEditor | undefined;
private _enabled: boolean = false;
constructor() {
constructor(private readonly container: Container) {
this._disposable = Disposable.from(
container.onReady(this.onReady, this),
configuration.onDidChange(this.onConfigurationChanged, this),
Container.fileAnnotations.onDidToggleAnnotations(this.onFileAnnotationsToggled, this),
container.fileAnnotations.onDidToggleAnnotations(this.onFileAnnotationsToggled, this),
Authentication.onDidChange(() => void this.refresh(window.activeTextEditor)),
);
this.onConfigurationChanged();
}
dispose() {
this.clearAnnotations(this._editor);
Container.lineTracker.stop(this);
this.container.lineTracker.stop(this);
this._disposable.dispose();
}
private onReady(): void {
this.onConfigurationChanged();
}
private onConfigurationChanged(e?: ConfigurationChangeEvent) {
if (!configuration.changed(e, 'currentLine')) return;
if (configuration.changed(e, 'currentLine.enabled')) {
if (Container.config.currentLine.enabled) {
if (this.container.config.currentLine.enabled) {
this._enabled = true;
this.resume();
} else {
@ -152,7 +156,7 @@ export class LineAnnotationController implements Disposable {
) {
if (lines.length === 0) return undefined;
const remote = await Container.git.getRichRemoteProvider(repoPath);
const remote = await this.container.git.getRichRemoteProvider(repoPath);
if (remote?.provider == null) return undefined;
const refs = new Set<string>();
@ -166,7 +170,7 @@ export class LineAnnotationController implements Disposable {
const { provider } = remote;
const prs = await Promises.raceAll(
refs.values(),
ref => Container.git.getPullRequestForCommit(ref, provider),
ref => this.container.git.getPullRequestForCommit(ref, provider),
timeout,
);
if (prs.size === 0 || Iterables.every(prs.values(), pr => pr == null)) return undefined;
@ -180,7 +184,7 @@ export class LineAnnotationController implements Disposable {
const cc = Logger.getCorrelationContext();
const selections = Container.lineTracker.selections;
const selections = this.container.lineTracker.selections;
if (editor == null || selections == null || !isTextEditor(editor)) {
if (cc != null) {
cc.exitDetails = ` ${GlyphChars.Dot} Skipped because there is no valid editor or no valid selections`;
@ -197,7 +201,7 @@ export class LineAnnotationController implements Disposable {
this._editor = editor;
}
const cfg = Container.config.currentLine;
const cfg = this.container.config.currentLine;
if (this.suspended) {
if (cc != null) {
cc.exitDetails = ` ${GlyphChars.Dot} Skipped because the controller is suspended`;
@ -207,7 +211,7 @@ export class LineAnnotationController implements Disposable {
return;
}
const trackedDocument = await Container.tracker.getOrAdd(editor.document);
const trackedDocument = await this.container.tracker.getOrAdd(editor.document);
if (!trackedDocument.isBlameable && this.suspended) {
if (cc != null) {
cc.exitDetails = ` ${GlyphChars.Dot} Skipped because the ${
@ -222,7 +226,7 @@ export class LineAnnotationController implements Disposable {
}
// Make sure the editor hasn't died since the await above and that we are still on the same line(s)
if (editor.document == null || !Container.lineTracker.includes(selections)) {
if (editor.document == null || !this.container.lineTracker.includes(selections)) {
if (cc != null) {
cc.exitDetails = ` ${GlyphChars.Dot} Skipped because the ${
editor.document == null
@ -243,7 +247,7 @@ export class LineAnnotationController implements Disposable {
const commitLines = [
...Iterables.filterMap<LineSelection, [number, GitBlameCommit]>(selections, selection => {
const state = Container.lineTracker.getState(selection.active);
const state = this.container.lineTracker.getState(selection.active);
if (state?.commit == null) {
Logger.debug(cc, `Line ${selection.active} returned no commit`);
return undefined;
@ -258,7 +262,7 @@ export class LineAnnotationController implements Disposable {
// TODO: Make this configurable?
const timeout = 100;
const [getBranchAndTagTips, prs] = await Promise.all([
CommitFormatter.has(cfg.format, 'tips') ? Container.git.getBranchesAndTagsTipsFn(repoPath) : undefined,
CommitFormatter.has(cfg.format, 'tips') ? this.container.git.getBranchesAndTagsTipsFn(repoPath) : undefined,
repoPath != null &&
cfg.pullRequests.enabled &&
CommitFormatter.has(
@ -293,7 +297,7 @@ export class LineAnnotationController implements Disposable {
// l,
cfg.format,
{
dateFormat: cfg.dateFormat === null ? Container.config.defaultDateFormat : cfg.dateFormat,
dateFormat: cfg.dateFormat === null ? this.container.config.defaultDateFormat : cfg.dateFormat,
getBranchAndTagTips: getBranchAndTagTips,
pullRequestOrRemote: prs?.get(commit.ref),
pullRequestPendingMessage: `PR ${GlyphChars.Ellipsis}`,
@ -312,17 +316,17 @@ export class LineAnnotationController implements Disposable {
private setLineTracker(enabled: boolean) {
if (enabled) {
if (!Container.lineTracker.isSubscribed(this)) {
Container.lineTracker.start(
if (!this.container.lineTracker.isSubscribed(this)) {
this.container.lineTracker.start(
this,
Container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this),
this.container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this),
);
}
return;
}
Container.lineTracker.stop(this);
this.container.lineTracker.stop(this);
}
private async waitForAnyPendingPullRequests(

+ 5
- 5
src/api/actionRunners.ts View File

@ -1,7 +1,7 @@
'use strict';
import { commands, Disposable, Event, EventEmitter, QuickPickItem, window } from 'vscode';
import { Commands } from '../commands/common';
import { configuration } from '../configuration';
import { Config, configuration } from '../configuration';
import { ContextKeys, setContext } from '../constants';
import { Container } from '../container';
import { getQuickPickIgnoreFocusOut } from '../quickpicks';
@ -128,7 +128,7 @@ export class ActionRunners implements Disposable {
private readonly _actionRunners = new Map<Actions, RegisteredActionRunner<any>[]>();
private readonly _disposable: Disposable;
constructor() {
constructor(private readonly container: Container) {
const subscriptions: Disposable[] = [
configuration.onDidChange(e => {
if (!configuration.changed(e, 'partners')) return;
@ -165,7 +165,7 @@ export class ActionRunners implements Disposable {
}
get(action: Actions): RegisteredActionRunner[] | undefined {
return filterOnlyEnabledRunners(this._actionRunners.get(action));
return filterOnlyEnabledRunners(this.container.config, this._actionRunners.get(action));
}
has(action: Actions): boolean {
@ -337,10 +337,10 @@ export class ActionRunners implements Disposable {
}
}
function filterOnlyEnabledRunners(runners: RegisteredActionRunner[] | undefined) {
function filterOnlyEnabledRunners(config: Config, runners: RegisteredActionRunner[] | undefined) {
if (runners == null || runners.length === 0) return undefined;
const partners = Container.config.partners;
const partners = config.partners;
if (partners == null) return runners;
return runners.filter(

+ 7
- 2
src/api/api.ts View File

@ -12,6 +12,11 @@ const emptyDisposable = Object.freeze({
});
export class Api implements GitLensApi {
readonly #container: Container;
constructor(container: Container) {
this.#container = container;
}
registerActionRunner<T extends ActionContext>(action: Action<T>, runner: ActionRunner): Disposable {
if (runner.name === builtInActionRunnerName) {
throw new Error(`Cannot use the reserved name '${builtInActionRunnerName}'`);
@ -20,7 +25,7 @@ export class Api implements GitLensApi {
if ((action as string) === 'hover.commandHelp') {
action = 'hover.commands';
}
return Container.actionRunners.register(action, runner);
return this.#container.actionRunners.register(action, runner);
}
// registerAutolinkProvider(provider: RemoteProvider): Disposable;
@ -39,7 +44,7 @@ export function preview() {
if (fn == null) throw new Error('Not supported');
descriptor.value = function (this: any, ...args: any[]) {
if (Container.insiders || Logger.isDebugging) return fn!.apply(this, args);
if (Container.instance.insiders || Logger.isDebugging) return fn!.apply(this, args);
console.error('GitLens preview APIs are only available in the Insiders edition');
return emptyDisposable;

+ 6
- 6
src/avatars.ts View File

@ -27,7 +27,7 @@ _onDidFetchAvatar.event(
),
]
: undefined;
void Container.context.globalState.update(GlobalState.Avatars, avatars);
void Container.instance.context.globalState.update(GlobalState.Avatars, avatars);
}, 1000),
);
@ -139,7 +139,7 @@ function createOrUpdateAvatar(
function ensureAvatarCache(cache: Map<string, Avatar> | undefined): asserts cache is Map<string, Avatar> {
if (cache == null) {
const avatars: [string, Avatar][] | undefined = Container.context.globalState
const avatars: [string, Avatar][] | undefined = Container.instance.context.globalState
.get<[string, SerializedAvatar][]>(GlobalState.Avatars)
?.map<[string, Avatar]>(([key, avatar]) => [
key,
@ -184,13 +184,13 @@ async function getAvatarUriFromRemoteProvider(
try {
let account;
if (Container.config.integrations.enabled) {
if (Container.instance.config.integrations.enabled) {
// if (typeof repoPathOrCommit === 'string') {
// const remote = await Container.git.getRichRemoteProvider(repoPathOrCommit);
// const remote = await Container.instance.git.getRichRemoteProvider(repoPathOrCommit);
// account = await remote?.provider.getAccountForEmail(email, { avatarSize: size });
// } else {
if (typeof repoPathOrCommit !== 'string') {
const remote = await Container.git.getRichRemoteProvider(repoPathOrCommit.repoPath);
const remote = await Container.instance.git.getRichRemoteProvider(repoPathOrCommit.repoPath);
account = await remote?.provider.getAccountForCommit(repoPathOrCommit.ref, { avatarSize: size });
}
}
@ -248,7 +248,7 @@ export function getPresenceDataUri(status: ContactPresenceStatus) {
export function resetAvatarCache(reset: 'all' | 'failed' | 'fallback') {
switch (reset) {
case 'all':
void Container.context.globalState.update(GlobalState.Avatars, undefined);
void Container.instance.context.globalState.update(GlobalState.Avatars, undefined);
avatarCache?.clear();
avatarQueue.clear();
break;

+ 14
- 8
src/codelens/codeLensController.ts View File

@ -17,9 +17,11 @@ export class GitCodeLensController implements Disposable {
private _provider: GitCodeLensProvider | undefined;
private _providerDisposable: Disposable | undefined;
constructor() {
this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this));
this.onConfigurationChanged();
constructor(private readonly container: Container) {
this._disposable = Disposable.from(
container.onReady(this.onReady, this),
configuration.onDidChange(this.onConfigurationChanged, this),
);
}
dispose() {
@ -27,6 +29,10 @@ export class GitCodeLensController implements Disposable {
this._disposable?.dispose();
}
private onReady(): void {
this.onConfigurationChanged();
}
private onConfigurationChanged(e?: ConfigurationChangeEvent) {
if (
configuration.changed(e, 'codeLens') ||
@ -38,7 +44,7 @@ export class GitCodeLensController implements Disposable {
Logger.log('CodeLens config changed; resetting CodeLens provider');
}
const cfg = Container.config.codeLens;
const cfg = this.container.config.codeLens;
if (cfg.enabled && (cfg.recentChange.enabled || cfg.authors.enabled)) {
this.ensureProvider();
} else {
@ -62,7 +68,7 @@ export class GitCodeLensController implements Disposable {
private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent<GitDocumentState>) {
if (this._provider === undefined || !e.document.isBlameable) return;
const maxLines = Container.config.advanced.blame.sizeThresholdAfterEdit;
const maxLines = this.container.config.advanced.blame.sizeThresholdAfterEdit;
if (maxLines > 0 && e.document.lineCount > maxLines) return;
Logger.log('Dirty idle triggered; resetting CodeLens provider');
@ -92,11 +98,11 @@ export class GitCodeLensController implements Disposable {
this._providerDisposable?.dispose();
this._provider = new GitCodeLensProvider(Container.context, Container.git, Container.tracker);
this._provider = new GitCodeLensProvider(this.container);
this._providerDisposable = Disposable.from(
languages.registerCodeLensProvider(GitCodeLensProvider.selector, this._provider),
Container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this),
Container.tracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this),
this.container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this),
this.container.tracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this),
);
}
}

+ 24
- 29
src/codelens/codeLensProvider.ts View File

@ -9,7 +9,6 @@ import {
DocumentSymbol,
Event,
EventEmitter,
ExtensionContext,
Location,
Position,
Range,
@ -40,11 +39,9 @@ import {
import { BuiltInCommands, DocumentSchemes } from '../constants';
import { Container } from '../container';
import { GitBlame, GitBlameLines, GitCommit, RemoteResourceType } from '../git/git';
import { GitService } from '../git/gitService';
import { GitUri } from '../git/gitUri';
import { Logger } from '../logger';
import { Functions, Iterables } from '../system';
import { DocumentTracker, GitDocumentState } from '../trackers/gitDocumentTracker';
export class GitRecentChangeCodeLens extends CodeLens {
constructor(
@ -86,11 +83,6 @@ export class GitAuthorsCodeLens extends CodeLens {
}
export class GitCodeLensProvider implements CodeLensProvider {
private _onDidChangeCodeLenses = new EventEmitter<void>();
get onDidChangeCodeLenses(): Event<void> {
return this._onDidChangeCodeLenses.event;
}
static selector: DocumentSelector = [
{ scheme: DocumentSchemes.File },
{ scheme: DocumentSchemes.Git },
@ -99,25 +91,26 @@ export class GitCodeLensProvider implements CodeLensProvider {
{ scheme: DocumentSchemes.Vsls },
];
constructor(
_context: ExtensionContext,
private readonly _git: GitService,
private readonly _tracker: DocumentTracker<GitDocumentState>,
) {}
private _onDidChangeCodeLenses = new EventEmitter<void>();
get onDidChangeCodeLenses(): Event<void> {
return this._onDidChangeCodeLenses.event;
}
constructor(private readonly container: Container) {}
reset(_reason?: 'idle' | 'saved') {
this._onDidChangeCodeLenses.fire();
}
async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
const trackedDocument = await this._tracker.getOrAdd(document);
const trackedDocument = await this.container.tracker.getOrAdd(document);
if (!trackedDocument.isBlameable) return [];
let dirty = false;
if (document.isDirty) {
// Only allow dirty blames if we are idle
if (trackedDocument.isDirtyIdle) {
const maxLines = Container.config.advanced.blame.sizeThresholdAfterEdit;
const maxLines = this.container.config.advanced.blame.sizeThresholdAfterEdit;
if (maxLines > 0 && document.lineCount > maxLines) {
dirty = true;
}
@ -157,13 +150,13 @@ export class GitCodeLensProvider implements CodeLensProvider {
if (languageScope.scopes.length === 1 && languageScope.scopes.includes(CodeLensScopes.Document)) {
blame = document.isDirty
? await this._git.getBlameForFileContents(gitUri, document.getText())
: await this._git.getBlameForFile(gitUri);
? await this.container.git.getBlameForFileContents(gitUri, document.getText())
: await this.container.git.getBlameForFile(gitUri);
} else {
[blame, symbols] = await Promise.all([
document.isDirty
? this._git.getBlameForFileContents(gitUri, document.getText())
: this._git.getBlameForFile(gitUri),
? this.container.git.getBlameForFileContents(gitUri, document.getText())
: this.container.git.getBlameForFile(gitUri),
commands.executeCommand(BuiltInCommands.ExecuteDocumentSymbolProvider, document.uri) as Promise<
SymbolInformation[]
>,
@ -217,7 +210,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
if (dirty || cfg.recentChange.enabled) {
if (!dirty) {
blameForRangeFn = Functions.once(() =>
this._git.getBlameForRangeSync(blame!, gitUri, blameRange),
this.container.git.getBlameForRangeSync(blame!, gitUri, blameRange),
);
}
@ -244,7 +237,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
if (!dirty && cfg.authors.enabled) {
if (blameForRangeFn === undefined) {
blameForRangeFn = Functions.once(() =>
this._git.getBlameForRangeSync(blame!, gitUri, blameRange),
this.container.git.getBlameForRangeSync(blame!, gitUri, blameRange),
);
}
@ -404,7 +397,9 @@ export class GitCodeLensProvider implements CodeLensProvider {
let blameForRangeFn: (() => GitBlameLines | undefined) | undefined;
if (dirty || cfg.recentChange.enabled) {
if (!dirty) {
blameForRangeFn = Functions.once(() => this._git.getBlameForRangeSync(blame!, gitUri!, blameRange));
blameForRangeFn = Functions.once(() =>
this.container.git.getBlameForRangeSync(blame!, gitUri!, blameRange),
);
}
lenses.push(
new GitRecentChangeCodeLens(
@ -446,7 +441,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
if (multiline && !dirty) {
if (blameForRangeFn === undefined) {
blameForRangeFn = Functions.once(() =>
this._git.getBlameForRangeSync(blame!, gitUri!, blameRange),
this.container.git.getBlameForRangeSync(blame!, gitUri!, blameRange),
);
}
lenses.push(
@ -496,7 +491,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
const recentCommit: GitCommit = Iterables.first(blame.commits.values());
// TODO@eamodio This is FAR too expensive, but this accounts for commits that delete lines -- is there another way?
// if (lens.uri != null) {
// const commit = await this._git.getCommitForFile(lens.uri.repoPath, lens.uri.fsPath, {
// const commit = await this.container.git.getCommitForFile(lens.uri.repoPath, lens.uri.fsPath, {
// range: lens.blameRange,
// });
// if (
@ -509,7 +504,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
// }
let title = `${recentCommit.author}, ${recentCommit.formattedDate}`;
if (Container.config.debug) {
if (this.container.config.debug) {
title += ` [${lens.languageId}: ${SymbolKind[lens.symbol.kind]}(${lens.range.start.character}-${
lens.range.end.character
}${
@ -580,7 +575,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
const author = Iterables.first(blame.authors.values()).name;
let title = `${count} ${count > 1 ? 'authors' : 'author'} (${author}${count > 1 ? ' and others' : ''})`;
if (Container.config.debug) {
if (this.container.config.debug) {
title += ` [${lens.languageId}: ${SymbolKind[lens.symbol.kind]}(${lens.range.start.character}-${
lens.range.end.character
}${
@ -871,10 +866,10 @@ export class GitCodeLensProvider implements CodeLensProvider {
private getDirtyTitle(cfg: CodeLensConfig) {
if (cfg.recentChange.enabled && cfg.authors.enabled) {
return Container.config.strings.codeLens.unsavedChanges.recentChangeAndAuthors;
return this.container.config.strings.codeLens.unsavedChanges.recentChangeAndAuthors;
}
if (cfg.recentChange.enabled) return Container.config.strings.codeLens.unsavedChanges.recentChangeOnly;
return Container.config.strings.codeLens.unsavedChanges.authorsOnly;
if (cfg.recentChange.enabled) return this.container.config.strings.codeLens.unsavedChanges.recentChangeOnly;
return this.container.config.strings.codeLens.unsavedChanges.authorsOnly;
}
}

+ 1
- 1
src/commands/addAuthors.ts View File

@ -13,7 +13,7 @@ export class AddAuthorsCommand extends Command {
async execute(sourceControl: SourceControl) {
let repo;
if (sourceControl?.rootUri != null) {
repo = await Container.git.getRepository(sourceControl.rootUri);
repo = await Container.instance.git.getRepository(sourceControl.rootUri);
}
return executeGitCommand({

+ 1
- 1
src/commands/browseRepoAtRevision.ts View File

@ -66,7 +66,7 @@ export class BrowseRepoAtRevisionCommand extends ActiveEditorCommand {
if (gitUri.sha == null) return;
const sha = args?.before
? await Container.git.resolveReference(gitUri.repoPath!, `${gitUri.sha}^`)
? await Container.instance.git.resolveReference(gitUri.repoPath!, `${gitUri.sha}^`)
: gitUri.sha;
uri = toGitLensFSUri(sha, gitUri.repoPath!);
gitUri = GitUri.fromRevisionUri(uri);

+ 1
- 1
src/commands/closeUnchangedFiles.ts View File

@ -28,7 +28,7 @@ export class CloseUnchangedFilesCommand extends Command {
const repoPath = await getRepoPathOrPrompt('Close All Unchanged Files');
if (!repoPath) return;
const status = await Container.git.getStatusForRepo(repoPath);
const status = await Container.instance.git.getStatusForRepo(repoPath);
if (status == null) {
void window.showWarningMessage('Unable to close unchanged files');

+ 1
- 1
src/commands/closeView.ts View File

@ -16,7 +16,7 @@ export class CloseViewCommand extends Command {
async execute(command: Commands) {
switch (command) {
case Commands.CloseWelcomeView:
await Container.context.globalState.update(SyncedState.WelcomeViewVisible, false);
await Container.instance.context.globalState.update(SyncedState.WelcomeViewVisible, false);
await setContext(ContextKeys.ViewsWelcomeVisible, false);
break;
}

+ 2
- 2
src/commands/common.ts View File

@ -230,7 +230,7 @@ export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined {
}
export async function getRepoPathOrActiveOrPrompt(uri: Uri | undefined, editor: TextEditor | undefined, title: string) {
const repoPath = await Container.git.getRepoPathOrActive(uri, editor);
const repoPath = await Container.instance.git.getRepoPathOrActive(uri, editor);
if (repoPath) return repoPath;
const pick = await RepositoryPicker.show(title);
@ -243,7 +243,7 @@ export async function getRepoPathOrActiveOrPrompt(uri: Uri | undefined, editor:
}
export async function getRepoPathOrPrompt(title: string, uri?: Uri) {
const repoPath = await Container.git.getRepoPath(uri);
const repoPath = await Container.instance.git.getRepoPath(uri);
if (repoPath) return repoPath;
const pick = await RepositoryPicker.show(title);

+ 2
- 2
src/commands/compareWith.ts View File

@ -76,9 +76,9 @@ export class CompareWithCommand extends ActiveEditorCommand {
if (!repoPath) return;
if (args.ref1 != null && args.ref2 != null) {
void (await Container.searchAndCompareView.compare(repoPath, args.ref1, args.ref2));
void (await Container.instance.searchAndCompareView.compare(repoPath, args.ref1, args.ref2));
} else {
Container.searchAndCompareView.selectForCompare(repoPath, args.ref1, { prompt: true });
Container.instance.searchAndCompareView.selectForCompare(repoPath, args.ref1, { prompt: true });
}
} catch (ex) {
Logger.error(ex, 'CompareWithCommmand');

+ 1
- 1
src/commands/copyCurrentBranch.ts View File

@ -20,7 +20,7 @@ export class CopyCurrentBranchCommand extends ActiveEditorCommand {
if (!repoPath) return;
try {
const branch = await Container.git.getBranch(repoPath);
const branch = await Container.instance.git.getBranch(repoPath);
if (branch?.name) {
await env.clipboard.writeText(branch.name);
}

+ 9
- 5
src/commands/copyMessageToClipboard.ts View File

@ -53,10 +53,10 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand {
let repoPath;
// If we don't have an editor then get the message of the last commit to the branch
if (uri == null) {
repoPath = await Container.git.getActiveRepoPath(editor);
repoPath = await Container.instance.git.getActiveRepoPath(editor);
if (!repoPath) return;
const log = await Container.git.getLog(repoPath, { limit: 1 });
const log = await Container.instance.git.getLog(repoPath, { limit: 1 });
if (log == null) return;
args.message = Iterables.first(log.commits.values()).message;
@ -70,8 +70,12 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand {
try {
const blame = editor?.document.isDirty
? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText())
: await Container.git.getBlameForLine(gitUri, blameline);
? await Container.instance.git.getBlameForLineContents(
gitUri,
blameline,
editor.document.getText(),
)
: await Container.instance.git.getBlameForLine(gitUri, blameline);
if (blame == null) return;
if (blame.commit.isUncommitted) return;
@ -89,7 +93,7 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand {
}
// Get the full commit message -- since blame only returns the summary
const commit = await Container.git.getCommit(repoPath!, args.sha);
const commit = await Container.instance.git.getCommit(repoPath!, args.sha);
if (commit == null) return;
args.message = commit.message;

+ 9
- 5
src/commands/copyShaToClipboard.ts View File

@ -29,7 +29,7 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand {
protected override preExecute(context: CommandContext, args?: CopyShaToClipboardCommandArgs) {
if (isCommandContextViewNodeHasCommit(context)) {
args = { ...args };
args.sha = Container.config.advanced.abbreviateShaOnCopy
args.sha = Container.instance.config.advanced.abbreviateShaOnCopy
? context.node.commit.shortSha
: context.node.commit.sha;
return this.execute(context.editor, context.node.commit.uri, args);
@ -53,10 +53,10 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand {
try {
// If we don't have an editor then get the sha of the last commit to the branch
if (uri == null) {
const repoPath = await Container.git.getActiveRepoPath(editor);
const repoPath = await Container.instance.git.getActiveRepoPath(editor);
if (!repoPath) return;
const log = await Container.git.getLog(repoPath, { limit: 1 });
const log = await Container.instance.git.getLog(repoPath, { limit: 1 });
if (log == null) return;
args.sha = Iterables.first(log.commits.values()).sha;
@ -67,8 +67,12 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand {
try {
const gitUri = await GitUri.fromUri(uri);
const blame = editor?.document.isDirty
? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText())
: await Container.git.getBlameForLine(gitUri, blameline);
? await Container.instance.git.getBlameForLineContents(
gitUri,
blameline,
editor.document.getText(),
)
: await Container.instance.git.getBlameForLine(gitUri, blameline);
if (blame == null) return;
args.sha = blame.commit.sha;

+ 1
- 1
src/commands/createPullRequestOnRemote.ts View File

@ -22,7 +22,7 @@ export class CreatePullRequestOnRemoteCommand extends Command {
async execute(args?: CreatePullRequestOnRemoteCommandArgs) {
if (args?.repoPath == null) return;
const repo = await Container.git.getRepository(args.repoPath);
const repo = await Container.instance.git.getRepository(args.repoPath);
if (repo == null) return;
const compareRemote = await repo.getRemote(args.remote);

+ 1
- 1
src/commands/diffLineWithPrevious.ts View File

@ -33,7 +33,7 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand {
const gitUri = args.commit != null ? GitUri.fromCommit(args.commit) : await GitUri.fromUri(uri);
try {
const diffUris = await Container.git.getPreviousLineDiffUris(
const diffUris = await Container.instance.git.getPreviousLineDiffUris(
gitUri.repoPath!,
gitUri,
args.line,

+ 3
- 3
src/commands/diffLineWithWorking.ts View File

@ -38,8 +38,8 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand {
try {
const blame = editor?.document.isDirty
? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText())
: await Container.git.getBlameForLine(gitUri, blameline);
? await Container.instance.git.getBlameForLineContents(gitUri, blameline, editor.document.getText())
: await Container.instance.git.getBlameForLine(gitUri, blameline);
if (blame == null) {
void Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare');
@ -50,7 +50,7 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand {
// If the line is uncommitted, change the previous commit
if (args.commit.isUncommitted) {
const status = await Container.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath);
const status = await Container.instance.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath);
args.commit = args.commit.with({
sha: status?.indexStatus != null ? GitRevision.uncommittedStaged : args.commit.previousSha!,
fileName: args.commit.previousFileName!,

+ 9
- 5
src/commands/diffWith.ts View File

@ -88,8 +88,12 @@ export class DiffWithCommand extends Command {
let rhsSha = args.rhs.sha;
[args.lhs.sha, args.rhs.sha] = await Promise.all([
await Container.git.resolveReference(args.repoPath, args.lhs.sha, args.lhs.uri, { timeout: 100 }),
await Container.git.resolveReference(args.repoPath, args.rhs.sha, args.rhs.uri, { timeout: 100 }),
await Container.instance.git.resolveReference(args.repoPath, args.lhs.sha, args.lhs.uri, {
timeout: 100,
}),
await Container.instance.git.resolveReference(args.repoPath, args.rhs.sha, args.rhs.uri, {
timeout: 100,
}),
]);
if (args.lhs.sha !== GitRevision.deletedOrMissing) {
@ -98,7 +102,7 @@ export class DiffWithCommand extends Command {
if (args.rhs.sha && args.rhs.sha !== GitRevision.deletedOrMissing) {
// Ensure that the file still exists in this commit
const status = await Container.git.getFileStatusForCommit(
const status = await Container.instance.git.getFileStatusForCommit(
args.repoPath,
args.rhs.uri.fsPath,
args.rhs.sha,
@ -115,8 +119,8 @@ export class DiffWithCommand extends Command {
}
const [lhs, rhs] = await Promise.all([
Container.git.getVersionedUri(args.repoPath, args.lhs.uri.fsPath, args.lhs.sha),
Container.git.getVersionedUri(args.repoPath, args.rhs.uri.fsPath, args.rhs.sha),
Container.instance.git.getVersionedUri(args.repoPath, args.lhs.uri.fsPath, args.lhs.sha),
Container.instance.git.getVersionedUri(args.repoPath, args.rhs.uri.fsPath, args.rhs.sha),
]);
let rhsSuffix = GitRevision.shorten(rhsSha, { strings: { uncommitted: 'Working Tree' } });

+ 1
- 1
src/commands/diffWithNext.ts View File

@ -42,7 +42,7 @@ export class DiffWithNextCommand extends ActiveEditorCommand {
const gitUri = args.commit != null ? GitUri.fromCommit(args.commit) : await GitUri.fromUri(uri);
try {
const diffUris = await Container.git.getNextDiffUris(
const diffUris = await Container.instance.git.getNextDiffUris(
gitUri.repoPath!,
gitUri,
gitUri.sha,

+ 1
- 1
src/commands/diffWithPrevious.ts View File

@ -83,7 +83,7 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
// }
try {
const diffUris = await Container.git.getPreviousDiffUris(
const diffUris = await Container.instance.git.getPreviousDiffUris(
gitUri.repoPath!,
gitUri,
gitUri.sha,

+ 2
- 2
src/commands/diffWithRevision.ts View File

@ -34,13 +34,13 @@ export class DiffWithRevisionCommand extends ActiveEditorCommand {
}
try {
const log = Container.git
const log = Container.instance.git
.getLogForFile(gitUri.repoPath, gitUri.fsPath)
.then(
log =>
log ??
(gitUri.sha
? Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { ref: gitUri.sha })
? Container.instance.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { ref: gitUri.sha })
: undefined),
);

+ 1
- 1
src/commands/diffWithRevisionFrom.ts View File

@ -57,7 +57,7 @@ export class DiffWithRevisionFromCommand extends ActiveEditorCommand {
let renamedTitle: string | undefined;
// Check to see if this file has been renamed
const files = await Container.git.getDiffStatus(gitUri.repoPath, 'HEAD', ref, { filters: ['R', 'C'] });
const files = await Container.instance.git.getDiffStatus(gitUri.repoPath, 'HEAD', ref, { filters: ['R', 'C'] });
if (files != null) {
const fileName = Strings.normalizePath(paths.relative(gitUri.repoPath, gitUri.fsPath));
const rename = files.find(s => s.fileName === fileName);

+ 8
- 3
src/commands/diffWithWorking.ts View File

@ -38,7 +38,12 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
if (args.inDiffRightEditor) {
try {
const diffUris = await Container.git.getPreviousDiffUris(gitUri.repoPath!, gitUri, gitUri.sha, 0);
const diffUris = await Container.instance.git.getPreviousDiffUris(
gitUri.repoPath!,
gitUri,
gitUri.sha,
0,
);
gitUri = diffUris?.previous ?? gitUri;
} catch (ex) {
Logger.error(
@ -66,7 +71,7 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
// If we are a fake "staged" sha, check the status
if (gitUri.isUncommittedStaged) {
const status = await Container.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath);
const status = await Container.instance.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath);
if (status?.indexStatus != null) {
void (await executeCommand<DiffWithCommandArgs>(Commands.DiffWith, {
repoPath: gitUri.repoPath,
@ -88,7 +93,7 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
uri = gitUri.toFileUri();
const workingUri = await Container.git.getWorkingUri(gitUri.repoPath!, uri);
const workingUri = await Container.instance.git.getWorkingUri(gitUri.repoPath!, uri);
if (workingUri == null) {
void window.showWarningMessage('Unable to open compare. File has been deleted from the working tree');

+ 8
- 6
src/commands/externalDiff.ts View File

@ -122,7 +122,7 @@ export class ExternalDiffCommand extends Command {
const repoPath = await getRepoPathOrPrompt('Open All Changes (difftool)');
if (!repoPath) return undefined;
const status = await Container.git.getStatusForRepo(repoPath);
const status = await Container.instance.git.getStatusForRepo(repoPath);
if (status == null) {
return window.showInformationMessage("The repository doesn't have any changes");
}
@ -158,11 +158,11 @@ export class ExternalDiffCommand extends Command {
const editor = window.activeTextEditor;
if (editor == null) return;
repoPath = await Container.git.getRepoPathOrActive(undefined, editor);
repoPath = await Container.instance.git.getRepoPathOrActive(undefined, editor);
if (!repoPath) return;
const uri = editor.document.uri;
const status = await Container.git.getStatusForFile(repoPath, uri.fsPath);
const status = await Container.instance.git.getStatusForFile(repoPath, uri.fsPath);
if (status == null) {
void window.showInformationMessage("The current file doesn't have any changes");
@ -178,11 +178,13 @@ export class ExternalDiffCommand extends Command {
args.files.push({ uri: status.uri, staged: false });
}
} else {
repoPath = await Container.git.getRepoPath(args.files[0].uri.fsPath);
repoPath = await Container.instance.git.getRepoPath(args.files[0].uri.fsPath);
if (!repoPath) return;
}
const tool = Container.config.advanced.externalDiffTool || (await Container.git.getDiffTool(repoPath));
const tool =
Container.instance.config.advanced.externalDiffTool ||
(await Container.instance.git.getDiffTool(repoPath));
if (!tool) {
const viewDocs = 'View Git Docs';
const result = await window.showWarningMessage(
@ -199,7 +201,7 @@ export class ExternalDiffCommand extends Command {
}
for (const file of args.files) {
void Container.git.openDiffTool(repoPath, file.uri, {
void Container.instance.git.openDiffTool(repoPath, file.uri, {
ref1: file.ref1,
ref2: file.ref2,
staged: file.staged,

+ 1
- 1
src/commands/git/branch.ts View File

@ -148,7 +148,7 @@ export class BranchGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
showTags: false,
title: this.title,
};

+ 2
- 2
src/commands/git/cherry-pick.ts View File

@ -80,7 +80,7 @@ export class CherryPickGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!,
selectedBranchOrTag: undefined,
@ -162,7 +162,7 @@ export class CherryPickGitCommand extends QuickCommand {
let log = context.cache.get(ref);
if (log == null) {
log = Container.git.getLog(state.repo.path, { ref: ref, merges: false });
log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false });
context.cache.set(ref, log);
}

+ 2
- 2
src/commands/git/coauthors.ts View File

@ -93,7 +93,7 @@ export class CoAuthorsGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
activeRepo: undefined,
title: this.title,
};
@ -106,7 +106,7 @@ export class CoAuthorsGitCommand extends QuickCommand {
);
// Ensure that the active repo is known to the built-in git
context.activeRepo = await Container.git.getActiveRepository();
context.activeRepo = await Container.instance.git.getActiveRepository();
if (
context.activeRepo != null &&
!gitApi.repositories.some(r => r.rootUri.fsPath === context.activeRepo!.path)

+ 2
- 2
src/commands/git/fetch.ts View File

@ -59,7 +59,7 @@ export class FetchGitCommand extends QuickCommand {
return state.repos[0].fetch({ branch: state.reference });
}
return Container.git.fetchAll(state.repos, {
return Container.instance.git.fetchAll(state.repos, {
all: state.flags.includes('--all'),
prune: state.flags.includes('--prune'),
});
@ -67,7 +67,7 @@ export class FetchGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
title: this.title,
};

+ 4
- 4
src/commands/git/log.ts View File

@ -76,7 +76,7 @@ export class LogGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
cache: new Map<string, Promise<GitLog | undefined>>(),
selectedBranchOrTag: undefined,
title: this.title,
@ -152,8 +152,8 @@ export class LogGitCommand extends QuickCommand {
if (log == null) {
log =
state.fileName != null
? Container.git.getLogForFile(state.repo.path, state.fileName, { ref: ref })
: Container.git.getLog(state.repo.path, { ref: ref });
? Container.instance.git.getLogForFile(state.repo.path, state.fileName, { ref: ref })
: Container.instance.git.getLog(state.repo.path, { ref: ref });
context.cache.set(ref, log);
}
@ -175,7 +175,7 @@ export class LogGitCommand extends QuickCommand {
}
if (!(state.reference instanceof GitLogCommit) || state.reference.isFile) {
state.reference = await Container.git.getCommit(state.repo.path, state.reference.ref);
state.reference = await Container.instance.git.getCommit(state.repo.path, state.reference.ref);
}
const result = yield* GitCommandsCommand.getSteps(

+ 3
- 3
src/commands/git/merge.ts View File

@ -76,7 +76,7 @@ export class MergeGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!,
pickCommit: false,
@ -159,7 +159,7 @@ export class MergeGitCommand extends QuickCommand {
let log = context.cache.get(ref);
if (log == null) {
log = Container.git.getLog(state.repo.path, { ref: ref, merges: false });
log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false });
context.cache.set(ref, log);
}
@ -195,7 +195,7 @@ export class MergeGitCommand extends QuickCommand {
}
private async *confirmStep(state: MergeStepState, context: Context): AsyncStepResultGenerator<Flags[]> {
const aheadBehind = await Container.git.getAheadBehindCommitCount(state.repo.path, [
const aheadBehind = await Container.instance.git.getAheadBehindCommitCount(state.repo.path, [
GitRevision.createRange(context.destination.name, state.reference.name),
]);
const count = aheadBehind != null ? aheadBehind.ahead + aheadBehind.behind : 0;

+ 2
- 2
src/commands/git/pull.ts View File

@ -68,12 +68,12 @@ export class PullGitCommand extends QuickCommand {
}
}
return Container.git.pullAll(state.repos, { rebase: state.flags.includes('--rebase') });
return Container.instance.git.pullAll(state.repos, { rebase: state.flags.includes('--rebase') });
}
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
title: this.title,
};

+ 3
- 3
src/commands/git/push.ts View File

@ -64,14 +64,14 @@ export class PushGitCommand extends QuickCommand {
if (index !== -1) {
if (!GitReference.isBranch(state.reference)) return Promise.resolve();
return Container.git.pushAll(state.repos, {
return Container.instance.git.pushAll(state.repos, {
force: false,
publish: { remote: state.flags[index + 1] },
reference: state.reference,
});
}
return Container.git.pushAll(state.repos, {
return Container.instance.git.pushAll(state.repos, {
force: state.flags.includes('--force'),
reference: state.reference,
});
@ -79,7 +79,7 @@ export class PushGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
title: this.title,
};

+ 4
- 4
src/commands/git/rebase.ts View File

@ -75,7 +75,7 @@ export class RebaseGitCommand extends QuickCommand {
async execute(state: RebaseStepState) {
let configs: string[] | undefined;
if (state.flags.includes('--interactive')) {
await Container.rebaseEditor.enableForNextUse();
await Container.instance.rebaseEditor.enableForNextUse();
let editor;
switch (env.appName) {
@ -97,7 +97,7 @@ export class RebaseGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!,
pickCommit: false,
@ -180,7 +180,7 @@ export class RebaseGitCommand extends QuickCommand {
let log = context.cache.get(ref);
if (log == null) {
log = Container.git.getLog(state.repo.path, { ref: ref, merges: false });
log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false });
context.cache.set(ref, log);
}
@ -216,7 +216,7 @@ export class RebaseGitCommand extends QuickCommand {
}
private async *confirmStep(state: RebaseStepState, context: Context): AsyncStepResultGenerator<Flags[]> {
const aheadBehind = await Container.git.getAheadBehindCommitCount(state.repo.path, [
const aheadBehind = await Container.instance.git.getAheadBehindCommitCount(state.repo.path, [
state.reference.refType === 'revision'
? GitRevision.createRange(state.reference.ref, context.destination.ref)
: GitRevision.createRange(context.destination.name, state.reference.name),

+ 2
- 2
src/commands/git/reset.ts View File

@ -71,7 +71,7 @@ export class ResetGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!,
title: this.title,
@ -118,7 +118,7 @@ export class ResetGitCommand extends QuickCommand {
let log = context.cache.get(ref);
if (log == null) {
log = Container.git.getLog(state.repo.path, { ref: ref, merges: false });
log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false });
context.cache.set(ref, log);
}

+ 2
- 2
src/commands/git/revert.ts View File

@ -73,7 +73,7 @@ export class RevertGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!,
title: this.title,
@ -122,7 +122,7 @@ export class RevertGitCommand extends QuickCommand {
let log = context.cache.get(ref);
if (log == null) {
log = Container.git.getLog(state.repo.path, { ref: ref, merges: false });
log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false });
context.cache.set(ref, log);
}

+ 5
- 5
src/commands/git/search.ts View File

@ -91,14 +91,14 @@ export class SearchGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
commit: undefined,
resultsKey: undefined,
resultsPromise: undefined,
title: this.title,
};
const cfg = Container.config.gitCommands.search;
const cfg = Container.instance.config.gitCommands.search;
if (state.matchAll == null) {
state.matchAll = cfg.matchAll;
}
@ -166,7 +166,7 @@ export class SearchGitCommand extends QuickCommand {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (state.showResultsInSideBar) {
void Container.searchAndCompareView.search(
void Container.instance.searchAndCompareView.search(
state.repo.path,
search,
{
@ -195,7 +195,7 @@ export class SearchGitCommand extends QuickCommand {
showInSideBarCommand: new ActionQuickPickItem(
'$(link-external) Show Results in Side Bar',
() =>
void Container.searchAndCompareView.search(
void Container.instance.searchAndCompareView.search(
repoPath,
search,
{
@ -212,7 +212,7 @@ export class SearchGitCommand extends QuickCommand {
showInSideBarButton: {
button: QuickCommandButtons.ShowResultsInSideBar,
onDidClick: () =>
void Container.searchAndCompareView.search(
void Container.instance.searchAndCompareView.search(
repoPath,
search,
{

+ 5
- 2
src/commands/git/show.ts View File

@ -76,7 +76,7 @@ export class ShowGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
title: this.title,
};
@ -110,7 +110,10 @@ export class ShowGitCommand extends QuickCommand {
state.reference.isFile
) {
if (state.reference != null && (!GitLogCommit.is(state.reference) || state.reference.isFile)) {
state.reference = await Container.git.getCommit(state.reference.repoPath, state.reference.ref);
state.reference = await Container.instance.git.getCommit(
state.reference.repoPath,
state.reference.ref,
);
}
if (state.counter < 2 || state.reference == null) {

+ 5
- 5
src/commands/git/stash.ts View File

@ -144,7 +144,7 @@ export class StashGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
title: this.title,
};
@ -258,7 +258,7 @@ export class StashGitCommand extends QuickCommand {
while (this.canStepsContinue(state)) {
if (state.counter < 3 || state.reference == null) {
const result: StepResult<GitStashReference> = yield* pickStashStep(state, context, {
stash: await Container.git.getStash(state.repo.path),
stash: await Container.instance.git.getStash(state.repo.path),
placeholder: (context, stash) =>
stash == null
? `No stashes found in ${state.repo.formattedName}`
@ -374,7 +374,7 @@ export class StashGitCommand extends QuickCommand {
while (this.canStepsContinue(state)) {
if (state.counter < 3 || state.reference == null) {
const result: StepResult<GitStashReference> = yield* pickStashStep(state, context, {
stash: await Container.git.getStash(state.repo.path),
stash: await Container.instance.git.getStash(state.repo.path),
placeholder: (context, stash) =>
stash == null ? `No stashes found in ${state.repo.formattedName}` : 'Choose a stash to delete',
picked: state.reference?.ref,
@ -435,7 +435,7 @@ export class StashGitCommand extends QuickCommand {
while (this.canStepsContinue(state)) {
if (state.counter < 3 || state.reference == null) {
const result: StepResult<GitStashCommit> = yield* pickStashStep(state, context, {
stash: await Container.git.getStash(state.repo.path),
stash: await Container.instance.git.getStash(state.repo.path),
placeholder: (context, stash) =>
stash == null ? `No stashes found in ${state.repo.formattedName}` : 'Choose a stash',
picked: state.reference?.ref,
@ -447,7 +447,7 @@ export class StashGitCommand extends QuickCommand {
}
// if (!(state.reference instanceof GitStashCommit)) {
// state.reference = await Container.git.getCommit(state.repo.path, state.reference.ref);
// state.reference = await Container.instance.git.getCommit(state.repo.path, state.reference.ref);
// }
const result = yield* GitCommandsCommand.getSteps(

+ 1
- 1
src/commands/git/status.ts View File

@ -55,7 +55,7 @@ export class StatusGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
status: undefined!,
title: this.title,
};

+ 2
- 2
src/commands/git/switch.ts View File

@ -88,7 +88,7 @@ export class SwitchGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
showTags: false,
title: this.title,
};
@ -146,7 +146,7 @@ export class SwitchGitCommand extends QuickCommand {
if (GitReference.isBranch(state.reference) && state.reference.remote) {
context.title = `Create Branch and ${this.title}`;
const branches = await Container.git.getBranches(state.reference.repoPath, {
const branches = await Container.instance.git.getBranches(state.reference.repoPath, {
filter: b => b.upstream?.name === state.reference!.name,
sort: { orderBy: BranchSorting.DateDesc },
});

+ 1
- 1
src/commands/git/tag.ts View File

@ -127,7 +127,7 @@ export class TagGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = {
repos: [...(await Container.git.getOrderedRepositories())],
repos: [...(await Container.instance.git.getOrderedRepositories())],
showTags: false,
title: this.title,
};

+ 35
- 31
src/commands/gitCommands.actions.ts View File

@ -35,7 +35,7 @@ export async function executeGitCommand(args: GitCommandsCommandArgs): Promise
}
async function ensureRepo(repo: string | Repository): Promise<Repository> {
return typeof repo === 'string' ? (await Container.git.getRepository(repo))! : repo;
return typeof repo === 'string' ? (await Container.instance.git.getRepository(repo))! : repo;
}
export namespace GitActions {
@ -152,17 +152,17 @@ export namespace GitActions {
) {
if (
!configuration.get(`views.${branch.remote ? 'remotes' : 'branches'}.reveal` as const) ||
(Container.repositoriesView.visible &&
!(branch.remote ? Container.remotesView.visible : Container.branchesView.visible))
(Container.instance.repositoriesView.visible &&
!(branch.remote ? Container.instance.remotesView.visible : Container.instance.branchesView.visible))
) {
return Container.repositoriesView.revealBranch(branch, options);
return Container.instance.repositoriesView.revealBranch(branch, options);
}
let node;
if (branch.remote) {
node = await Container.remotesView.revealBranch(branch, options);
node = await Container.instance.remotesView.revealBranch(branch, options);
} else {
node = await Container.branchesView.revealBranch(branch, options);
node = await Container.instance.branchesView.revealBranch(branch, options);
}
return node;
@ -177,7 +177,7 @@ export namespace GitActions {
) {
// Open the working file to ensure undo will work
void (await GitActions.Commit.openFile(file, ref1, { preserveFocus: true, preview: false }));
void (await Container.git.applyChangesToWorkingFile(
void (await Container.instance.git.applyChangesToWorkingFile(
GitUri.fromFile(file, ref1.repoPath, ref1.ref),
ref1.ref,
ref2?.ref,
@ -193,7 +193,7 @@ export namespace GitActions {
if (GitLogCommit.is(ref)) {
message = ref.message;
} else {
const commit = await Container.git.getCommit(ref.repoPath, ref.ref);
const commit = await Container.instance.git.getCommit(ref.repoPath, ref.ref);
if (commit == null) return;
message = commit.message;
@ -399,7 +399,7 @@ export namespace GitActions {
file = f;
}
return Container.git.openDiffTool(
return Container.instance.git.openDiffTool(
commitOrRef.repoPath,
GitUri.fromFile(file, file.repoPath ?? commitOrRef.repoPath),
{
@ -461,7 +461,7 @@ export namespace GitActions {
ref2: string | undefined,
tool?: string,
): Promise<void> {
return Container.git.openDirectoryCompare(repoPath, ref, ref2, tool);
return Container.instance.git.openDirectoryCompare(repoPath, ref, ref2, tool);
}
export async function openDirectoryCompareWithPrevious(
@ -558,7 +558,9 @@ export namespace GitActions {
const editor = await findOrOpenEditor(uri, opts);
if (annotationType != null && editor != null) {
void (await Container.fileAnnotations.show(editor, annotationType, { selection: { line: line } }));
void (await Container.instance.fileAnnotations.show(editor, annotationType, {
selection: { line: line },
}));
}
}
@ -589,7 +591,9 @@ export namespace GitActions {
const uris: Uri[] = (
await Promise.all(
files.map(file => Container.git.getWorkingUri(repoPath!, GitUri.fromFile(file, repoPath!, ref))),
files.map(file =>
Container.instance.git.getWorkingUri(repoPath!, GitUri.fromFile(file, repoPath!, ref)),
),
)
).filter(<T>(u?: T): u is T => Boolean(u));
findOrOpenEditors(uris);
@ -633,7 +637,7 @@ export namespace GitActions {
}
export async function restoreFile(file: string | GitFile, ref: GitRevisionReference) {
void (await Container.git.checkout(ref.repoPath, ref.ref, {
void (await Container.instance.git.checkout(ref.repoPath, ref.ref, {
fileName: typeof file === 'string' ? file : file.fileName,
}));
}
@ -648,20 +652,20 @@ export namespace GitActions {
) {
if (
!configuration.get('views.commits.reveal') ||
(Container.repositoriesView.visible && !Container.commitsView.visible)
(Container.instance.repositoriesView.visible && !Container.instance.commitsView.visible)
) {
return Container.repositoriesView.revealCommit(commit, options);
return Container.instance.repositoriesView.revealCommit(commit, options);
}
// TODO@eamodio stop duplicate notifications
let node = await Container.commitsView.revealCommit(commit, options);
let node = await Container.instance.commitsView.revealCommit(commit, options);
if (node != null) return node;
node = await Container.branchesView.revealCommit(commit, options);
node = await Container.instance.branchesView.revealCommit(commit, options);
if (node != null) return node;
node = await Container.remotesView.revealCommit(commit, options);
node = await Container.instance.remotesView.revealCommit(commit, options);
if (node != null) return node;
return undefined;
@ -711,12 +715,12 @@ export namespace GitActions {
) {
if (
!configuration.get('views.tags.reveal') ||
(Container.repositoriesView.visible && !Container.tagsView.visible)
(Container.instance.repositoriesView.visible && !Container.instance.tagsView.visible)
) {
return Container.repositoriesView.revealTag(tag, options);
return Container.instance.repositoriesView.revealTag(tag, options);
}
const node = await Container.tagsView.revealTag(tag, options);
const node = await Container.instance.tagsView.revealTag(tag, options);
return node;
}
}
@ -724,7 +728,7 @@ export namespace GitActions {
export namespace Remote {
export async function add(repo?: string | Repository) {
if (repo == null) {
repo = Container.git.getHighlanderRepoPath();
repo = Container.instance.git.getHighlanderRepoPath();
if (repo == null) {
const pick = await RepositoryPicker.show(undefined, 'Choose a repository to add a remote to');
@ -750,7 +754,7 @@ export namespace GitActions {
if (url == null || url.length === 0) return undefined;
repo = await ensureRepo(repo);
void (await Container.git.addRemote(repo.path, name, url));
void (await Container.instance.git.addRemote(repo.path, name, url));
void (await repo.fetch({ remote: name }));
return name;
@ -758,7 +762,7 @@ export namespace GitActions {
export async function fetch(repo: string | Repository, remote: string) {
if (typeof repo === 'string') {
const r = await Container.git.getRepository(repo);
const r = await Container.instance.git.getRepository(repo);
if (r == null) return;
repo = r;
@ -768,7 +772,7 @@ export namespace GitActions {
}
export async function prune(repo: string | Repository, remote: string) {
void (await Container.git.pruneRemote(typeof repo === 'string' ? repo : repo.path, remote));
void (await Container.instance.git.pruneRemote(typeof repo === 'string' ? repo : repo.path, remote));
}
export async function reveal(
@ -781,12 +785,12 @@ export namespace GitActions {
) {
// if (
// configuration.get('views.repositories.enabled') &&
// (Container.repositoriesView.visible || !Container.remotesView.visible)
// (Container.instance.repositoriesView.visible || !Container.instance.remotesView.visible)
// ) {
// return Container.repositoriesView.revealRemote(remote, options);
// return Container.instance.repositoriesView.revealRemote(remote, options);
// }
const node = await Container.remotesView.revealRemote(remote, options);
const node = await Container.instance.remotesView.revealRemote(remote, options);
return node;
}
}
@ -836,12 +840,12 @@ export namespace GitActions {
) {
if (
!configuration.get('views.stashes.reveal') ||
(Container.repositoriesView.visible && !Container.stashesView.visible)
(Container.instance.repositoriesView.visible && !Container.instance.stashesView.visible)
) {
return Container.repositoriesView.revealStash(stash, options);
return Container.instance.repositoriesView.revealStash(stash, options);
}
const node = await Container.stashesView.revealStash(stash, options);
const node = await Container.instance.stashesView.revealStash(stash, options);
return node;
}
}

+ 6
- 6
src/commands/gitCommands.ts View File

@ -310,7 +310,7 @@ export class GitCommandsCommand extends Command {
}
}
const scope = Container.keyboard.createScope(mapping);
const scope = Container.instance.keyboard.createScope(mapping);
void scope.start();
disposables.push(
@ -460,7 +460,7 @@ export class GitCommandsCommand extends Command {
}
}
const scope = Container.keyboard.createScope(mapping);
const scope = Container.instance.keyboard.createScope(mapping);
void scope.start();
let overrideItems = false;
@ -767,8 +767,8 @@ class PickCommandStep implements QuickPickStep {
new TagGitCommand(args?.command === 'tag' ? args : undefined),
];
if (Container.config.gitCommands.sortBy === GitCommandSorting.Usage) {
const usage = Container.context.workspaceState.get<Usage>(WorkspaceState.GitCommandPaletteUsage);
if (Container.instance.config.gitCommands.sortBy === GitCommandSorting.Usage) {
const usage = Container.instance.context.workspaceState.get<Usage>(WorkspaceState.GitCommandPaletteUsage);
if (usage != null) {
this.items.sort((a, b) => (usage[b.key] ?? 0) - (usage[a.key] ?? 0));
}
@ -808,12 +808,12 @@ class PickCommandStep implements QuickPickStep {
}
private async updateCommandUsage(id: string, timestamp: number) {
let usage = Container.context.workspaceState.get<Usage>(WorkspaceState.GitCommandPaletteUsage);
let usage = Container.instance.context.workspaceState.get<Usage>(WorkspaceState.GitCommandPaletteUsage);
if (usage === undefined) {
usage = Object.create(null) as Usage;
}
usage[id] = timestamp;
await Container.context.workspaceState.update(WorkspaceState.GitCommandPaletteUsage, usage);
await Container.instance.context.workspaceState.update(WorkspaceState.GitCommandPaletteUsage, usage);
}
}

+ 2
- 2
src/commands/inviteToLiveShare.ts View File

@ -32,12 +32,12 @@ export class InviteToLiveShareCommand extends Command {
async execute(args?: InviteToLiveShareCommandArgs) {
if (args?.email) {
const contact = await Container.vsls.getContact(args.email);
const contact = await Container.instance.vsls.getContact(args.email);
if (contact != null) {
return contact.invite();
}
}
return Container.vsls.startSession();
return Container.instance.vsls.startSession();
}
}

+ 1
- 1
src/commands/openAssociatedPullRequestOnRemote.ts View File

@ -24,7 +24,7 @@ export class OpenAssociatedPullRequestOnRemoteCommand extends ActiveEditorComman
if (blameline < 0) return;
try {
const blame = await Container.git.getBlameForLine(gitUri, blameline);
const blame = await Container.instance.git.getBlameForLine(gitUri, blameline);
if (blame == null) return;
await executeCommand<OpenPullRequestOnRemoteCommandArgs>(Commands.OpenPullRequestOnRemote, {

+ 1
- 1
src/commands/openChangedFiles.ts View File

@ -24,7 +24,7 @@ export class OpenChangedFilesCommand extends Command {
const repoPath = await getRepoPathOrPrompt('Open All Changed Files');
if (!repoPath) return;
const status = await Container.git.getStatusForRepo(repoPath);
const status = await Container.instance.git.getStatusForRepo(repoPath);
if (status == null) {
void window.showWarningMessage('Unable to open changed files');

+ 2
- 2
src/commands/openCommitOnRemote.ts View File

@ -72,8 +72,8 @@ export class OpenCommitOnRemoteCommand extends ActiveEditorCommand {
if (blameline < 0) return;
const blame = editor?.document.isDirty
? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText())
: await Container.git.getBlameForLine(gitUri, blameline);
? await Container.instance.git.getBlameForLineContents(gitUri, blameline, editor.document.getText())
: await Container.instance.git.getBlameForLine(gitUri, blameline);
if (blame == null) {
void Messages.showFileNotUnderSourceControlWarningMessage(
'Unable to open commit on remote provider',

+ 5
- 3
src/commands/openFileAtRevision.ts View File

@ -57,7 +57,7 @@ export class OpenFileAtRevisionCommand extends ActiveEditorCommand {
if (blameline >= 0) {
try {
const gitUri = await GitUri.fromUri(context.editor.document.uri);
const blame = await Container.git.getBlameForLine(gitUri, blameline);
const blame = await Container.instance.git.getBlameForLine(gitUri, blameline);
if (blame != null && !blame.commit.isUncommitted && blame.commit.previousSha != null) {
args.revisionUri = GitUri.toRevisionUri(GitUri.fromCommit(blame.commit, true));
}
@ -82,13 +82,15 @@ export class OpenFileAtRevisionCommand extends ActiveEditorCommand {
try {
if (args.revisionUri == null) {
const log = Container.git
const log = Container.instance.git
.getLogForFile(gitUri.repoPath, gitUri.fsPath)
.then(
log =>
log ??
(gitUri.sha
? Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { ref: gitUri.sha })
? Container.instance.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, {
ref: gitUri.sha,
})
: undefined),
);

+ 2
- 2
src/commands/openFileFromRemote.ts View File

@ -25,9 +25,9 @@ export class OpenFileFromRemoteCommand extends Command {
});
if (url == null || url.length === 0) return;
let local = await Container.git.getLocalInfoFromRemoteUri(Uri.parse(url));
let local = await Container.instance.git.getLocalInfoFromRemoteUri(Uri.parse(url));
if (local == null) {
local = await Container.git.getLocalInfoFromRemoteUri(Uri.parse(url), { validate: false });
local = await Container.instance.git.getLocalInfoFromRemoteUri(Uri.parse(url), { validate: false });
if (local == null) {
void window.showWarningMessage('Unable to parse the provided remote url.');

+ 9
- 5
src/commands/openFileOnRemote.ts View File

@ -83,9 +83,13 @@ export class OpenFileOnRemoteCommand extends ActiveEditorCommand {
const gitUri = await GitUri.fromUri(uri);
if (gitUri.repoPath) {
if (gitUri.sha == null) {
const commit = await Container.git.getCommitForFile(gitUri.repoPath, gitUri.fsPath, {
firstIfNotFound: true,
});
const commit = await Container.instance.git.getCommitForFile(
gitUri.repoPath,
gitUri.fsPath,
{
firstIfNotFound: true,
},
);
if (commit != null) {
args.sha = commit.sha;
@ -115,7 +119,7 @@ export class OpenFileOnRemoteCommand extends ActiveEditorCommand {
args = { range: true, ...args };
try {
let remotes = await Container.git.getRemotes(gitUri.repoPath);
let remotes = await Container.instance.git.getRemotes(gitUri.repoPath);
const range =
args.range && editor != null && UriComparer.equals(editor.document.uri, uri)
? new Range(
@ -143,7 +147,7 @@ export class OpenFileOnRemoteCommand extends ActiveEditorCommand {
if ((args.sha == null && args.branchOrTag == null) || args.pickBranchOrTag) {
let branch;
if (!args.pickBranchOrTag) {
branch = await Container.git.getBranch(gitUri.repoPath);
branch = await Container.instance.git.getBranch(gitUri.repoPath);
}
if (branch?.upstream == null) {

+ 2
- 2
src/commands/openOnRemote.ts View File

@ -33,7 +33,7 @@ export class OpenOnRemoteCommand extends Command {
async execute(args?: OpenOnRemoteCommandArgs) {
if (args?.resource == null) return;
let remotes = 'remotes' in args ? args.remotes : await Container.git.getRemotes(args.repoPath);
let remotes = 'remotes' in args ? args.remotes : await Container.instance.git.getRemotes(args.repoPath);
if (args.remote != null) {
const filtered = remotes.filter(r => r.name === args.remote);
@ -60,7 +60,7 @@ export class OpenOnRemoteCommand extends Command {
const file = commit?.files.find(f => f.fileName === fileName);
if (file?.status === 'D') {
// Resolve to the previous commit to that file
args.resource.sha = await Container.git.resolveReference(
args.resource.sha = await Container.instance.git.resolveReference(
commit.repoPath,
`${commit.sha}^`,
fileName,

+ 2
- 2
src/commands/openPullRequestOnRemote.ts View File

@ -33,10 +33,10 @@ export class OpenPullRequestOnRemoteCommand extends Command {
if (args?.pr == null) {
if (args?.repoPath == null || args?.ref == null) return;
const remote = await Container.git.getRichRemoteProvider(args.repoPath);
const remote = await Container.instance.git.getRichRemoteProvider(args.repoPath);
if (remote?.provider == null) return;
const pr = await Container.git.getPullRequestForCommit(args.ref, remote.provider);
const pr = await Container.instance.git.getPullRequestForCommit(args.ref, remote.provider);
if (pr == null) return;
args = { ...args };

+ 1
- 1
src/commands/openRevisionFile.ts View File

@ -36,7 +36,7 @@ export class OpenRevisionFileCommand extends ActiveEditorCommand {
try {
if (args.revisionUri == null) {
if (gitUri?.sha) {
const commit = await Container.git.getCommit(gitUri.repoPath!, gitUri.sha);
const commit = await Container.instance.git.getCommit(gitUri.repoPath!, gitUri.sha);
args.revisionUri =
commit != null && commit.status === 'D'

+ 4
- 2
src/commands/openWorkingFile.ts View File

@ -36,7 +36,7 @@ export class OpenWorkingFileCommand extends ActiveEditorCommand {
args.uri = await GitUri.fromUri(uri);
if (GitUri.is(args.uri) && args.uri.sha) {
const workingUri = await Container.git.getWorkingUri(args.uri.repoPath!, args.uri);
const workingUri = await Container.instance.git.getWorkingUri(args.uri.repoPath!, args.uri);
if (workingUri === undefined) {
void window.showWarningMessage(
'Unable to open working file. File could not be found in the working tree',
@ -58,7 +58,9 @@ export class OpenWorkingFileCommand extends ActiveEditorCommand {
const e = await findOrOpenEditor(args.uri, { ...args.showOptions, throwOnError: true });
if (args.annotationType === undefined) return;
void (await Container.fileAnnotations.show(e, args.annotationType, { selection: { line: args.line } }));
void (await Container.instance.fileAnnotations.show(e, args.annotationType, {
selection: { line: args.line },
}));
} catch (ex) {
Logger.error(ex, 'OpenWorkingFileCommand');
void Messages.showGenericErrorMessage('Unable to open working file');

+ 8
- 6
src/commands/quickCommand.buttons.ts View File

@ -20,8 +20,8 @@ export class ToggleQuickInputButton implements QuickInputButton {
const icon = this.getToggledState().icon;
return typeof icon === 'string'
? {
dark: Uri.file(Container.context.asAbsolutePath(`images/dark/${icon}.svg`)),
light: Uri.file(Container.context.asAbsolutePath(`images/light/${icon}.svg`)),
dark: Uri.file(Container.instance.context.asAbsolutePath(`images/dark/${icon}.svg`)),
light: Uri.file(Container.instance.context.asAbsolutePath(`images/light/${icon}.svg`)),
}
: icon;
}
@ -133,15 +133,17 @@ export namespace QuickCommandButtons {
on: {
tooltip: 'Will confirm',
icon: {
dark: Uri.file(Container.context.asAbsolutePath('images/dark/icon-check.svg')),
light: Uri.file(Container.context.asAbsolutePath('images/light/icon-check.svg')),
dark: Uri.file(Container.instance.context.asAbsolutePath('images/dark/icon-check.svg')),
light: Uri.file(Container.instance.context.asAbsolutePath('images/light/icon-check.svg')),
},
},
off: {
tooltip: 'Skips confirm',
icon: {
dark: Uri.file(Container.context.asAbsolutePath('images/dark/icon-no-check.svg')),
light: Uri.file(Container.context.asAbsolutePath('images/light/icon-no-check.svg')),
dark: Uri.file(Container.instance.context.asAbsolutePath('images/dark/icon-no-check.svg')),
light: Uri.file(
Container.instance.context.asAbsolutePath('images/light/icon-no-check.svg'),
),
},
},
}),

+ 52
- 26
src/commands/quickCommand.steps.ts View File

@ -315,7 +315,7 @@ export function getValidateGitReferenceFn(
return true;
}
if (!(await Container.git.validateReference(repos.path, value))) {
if (!(await Container.instance.git.validateReference(repos.path, value))) {
if (inRefMode) {
quickpick.items = [
DirectiveQuickPickItem.create(Directive.Back, true, {
@ -330,7 +330,7 @@ export function getValidateGitReferenceFn(
if (!inRefMode) {
if (
await Container.git.hasBranchesAndOrTags(repos.path, {
await Container.instance.git.hasBranchesAndOrTags(repos.path, {
filter: { branches: b => b.name.includes(value), tags: t => t.name.includes(value) },
})
) {
@ -338,7 +338,7 @@ export function getValidateGitReferenceFn(
}
}
const commit = await Container.git.getCommit(repos.path, value);
const commit = await Container.instance.git.getCommit(repos.path, value);
quickpick.items = [
CommitQuickPickItem.create(commit!, true, {
alwaysShow: true,
@ -370,8 +370,21 @@ export async function* inputBranchNameStep<
value = value.trim();
if (value.length === 0) return [false, 'Please enter a valid branch name'];
const valid = await Container.git.validateBranchOrTagName(value);
return [valid, valid ? undefined : `'${value}' isn't a valid branch name`];
if ('repo' in state) {
const valid = await Container.instance.git.validateBranchOrTagName(state.repo.path, value);
return [valid, valid ? undefined : `'${value}' isn't a valid branch name`];
}
let valid = true;
for (const repo of state.repos) {
valid = await Container.instance.git.validateBranchOrTagName(repo.path, value);
if (!valid) {
return [false, `'${value}' isn't a valid branch name`];
}
}
return [true, undefined];
},
});
@ -405,8 +418,21 @@ export async function* inputTagNameStep<
value = value.trim();
if (value.length === 0) return [false, 'Please enter a valid tag name'];
const valid = await Container.git.validateBranchOrTagName(value);
return [valid, valid ? undefined : `'${value}' isn't a valid tag name`];
if ('repo' in state) {
const valid = await Container.instance.git.validateBranchOrTagName(state.repo.path, value);
return [valid, valid ? undefined : `'${value}' isn't a valid tag name`];
}
let valid = true;
for (const repo of state.repos) {
valid = await Container.instance.git.validateBranchOrTagName(repo.path, value);
if (!valid) {
return [false, `'${value}' isn't a valid branch name`];
}
}
return [true, undefined];
},
});
@ -830,7 +856,7 @@ export async function* pickCommitStep<
break;
case QuickCommandButtons.SearchInSideBar:
void Container.searchAndCompareView.search(
void Container.instance.searchAndCompareView.search(
state.repo.path,
{ pattern: SearchPattern.fromCommit(item.item.ref) },
{
@ -874,7 +900,7 @@ export async function* pickCommitStep<
});
} else {
const commit = items[0].item;
await Container.searchAndCompareView.search(
await Container.instance.searchAndCompareView.search(
commit.repoPath,
{ pattern: SearchPattern.fromCommit(commit) },
{
@ -974,7 +1000,7 @@ export function* pickCommitsStep<
break;
case QuickCommandButtons.SearchInSideBar:
void Container.searchAndCompareView.search(
void Container.instance.searchAndCompareView.search(
state.repo.path,
{ pattern: SearchPattern.fromCommit(item.ref) },
{
@ -1003,7 +1029,7 @@ export function* pickCommitsStep<
});
} else {
const commit = quickpick.activeItems[0].item;
await Container.searchAndCompareView.search(
await Container.instance.searchAndCompareView.search(
commit.repoPath,
{ pattern: SearchPattern.fromCommit(commit) },
{
@ -1038,7 +1064,7 @@ export async function* pickContributorsStep<
multiselect: true,
placeholder: placeholder,
matchOnDescription: true,
items: (await Container.git.getContributors(state.repo.path)).map(c =>
items: (await Container.instance.git.getContributors(state.repo.path)).map(c =>
ContributorQuickPickItem.create(c, message?.includes(c.toCoauthor())),
),
});
@ -1051,10 +1077,10 @@ export async function* pickRepositoryStep<
Context extends { repos: Repository[]; title: string },
>(state: State, context: Context, placeholder: string = 'Choose a repository'): AsyncStepResultGenerator<Repository> {
if (typeof state.repo === 'string') {
state.repo = await Container.git.getRepository(state.repo);
state.repo = await Container.instance.git.getRepository(state.repo);
if (state.repo != null) return state.repo;
}
const active = state.repo ?? (await Container.git.getActiveRepository());
const active = state.repo ?? (await Container.instance.git.getActiveRepository());
const step = QuickCommand.createPickStep<RepositoryQuickPickItem>({
title: context.title,
@ -1074,7 +1100,7 @@ export async function* pickRepositoryStep<
),
onDidClickItemButton: (quickpick, button, { item }) => {
if (button === QuickCommandButtons.RevealInSideBar) {
void Container.repositoriesView.revealRepository(item.path, {
void Container.instance.repositoriesView.revealRepository(item.path, {
select: true,
expand: true,
});
@ -1084,7 +1110,7 @@ export async function* pickRepositoryStep<
onDidPressKey: quickpick => {
if (quickpick.activeItems.length === 0) return;
void Container.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, {
void Container.instance.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, {
select: true,
focus: false,
expand: true,
@ -1116,7 +1142,7 @@ export async function* pickRepositoriesStep<
actives = state.repos;
}
} else {
const active = await Container.git.getActiveRepository();
const active = await Container.instance.git.getActiveRepository();
actives = active != null ? [active] : [];
}
@ -1143,7 +1169,7 @@ export async function* pickRepositoriesStep<
),
onDidClickItemButton: (quickpick, button, { item }) => {
if (button === QuickCommandButtons.RevealInSideBar) {
void Container.repositoriesView.revealRepository(item.path, {
void Container.instance.repositoriesView.revealRepository(item.path, {
select: true,
expand: true,
});
@ -1153,7 +1179,7 @@ export async function* pickRepositoriesStep<
onDidPressKey: quickpick => {
if (quickpick.activeItems.length === 0) return;
void Container.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, {
void Container.instance.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, {
select: true,
focus: false,
expand: true,
@ -1312,7 +1338,7 @@ export async function* showCommitOrStashStep<
: [QuickCommandButtons.RevealInSideBar, QuickCommandButtons.SearchInSideBar],
onDidClickButton: (quickpick, button) => {
if (button === QuickCommandButtons.SearchInSideBar) {
void Container.searchAndCompareView.search(
void Container.instance.searchAndCompareView.search(
state.repo.path,
{ pattern: SearchPattern.fromCommit(state.reference.ref) },
{
@ -1360,7 +1386,7 @@ async function getShowCommitOrStashStepItems<
>(state: State) {
const items: CommandQuickPickItem[] = [new CommitFilesQuickPickItem(state.reference)];
const branch = await Container.git.getBranch(state.repo.path);
const branch = await Container.instance.git.getBranch(state.repo.path);
let remotes: GitRemote<RemoteProvider>[] | undefined;
let isStash = false;
@ -1389,7 +1415,7 @@ async function getShowCommitOrStashStepItems<
}),
);
} else {
remotes = await Container.git.getRemotes(state.repo.path, { sort: true });
remotes = await Container.instance.git.getRemotes(state.repo.path, { sort: true });
items.push(
new RevealInSideBarQuickPickItem(state.reference),
@ -1398,7 +1424,7 @@ async function getShowCommitOrStashStepItems<
if (
branch != null &&
(await Container.git.branchContainsCommit(state.repo.path, branch.name, state.reference.ref))
(await Container.instance.git.branchContainsCommit(state.repo.path, branch.name, state.reference.ref))
) {
items.push(
new GitCommandQuickPickItem('Revert Commit...', {
@ -1567,7 +1593,7 @@ export function* showCommitOrStashFilesStep<
additionalButtons: [QuickCommandButtons.RevealInSideBar, QuickCommandButtons.SearchInSideBar],
onDidClickButton: (quickpick, button) => {
if (button === QuickCommandButtons.SearchInSideBar) {
void Container.searchAndCompareView.search(
void Container.instance.searchAndCompareView.search(
state.repo.path,
{ pattern: SearchPattern.fromCommit(state.reference.ref) },
{
@ -1639,7 +1665,7 @@ export async function* showCommitOrStashFileStep<
additionalButtons: [QuickCommandButtons.RevealInSideBar, QuickCommandButtons.SearchInSideBar],
onDidClickButton: (quickpick, button) => {
if (button === QuickCommandButtons.SearchInSideBar) {
void Container.searchAndCompareView.search(
void Container.instance.searchAndCompareView.search(
state.repo.path,
{ pattern: SearchPattern.fromCommit(state.reference.ref) },
{
@ -1704,7 +1730,7 @@ async function getShowCommitOrStashFileStepItems<
items.push(new RevealInSideBarQuickPickItem(state.reference));
} else {
remotes = await Container.git.getRemotes(state.repo.path, { sort: true });
remotes = await Container.instance.git.getRemotes(state.repo.path, { sort: true });
items.push(
new RevealInSideBarQuickPickItem(state.reference),

+ 1
- 1
src/commands/quickCommand.ts View File

@ -147,7 +147,7 @@ export abstract class QuickCommand implements QuickPickItem {
return override != null
? override
: !Container.config.gitCommands.skipConfirmations.includes(this.skipConfirmKey);
: !Container.instance.config.gitCommands.skipConfirmations.includes(this.skipConfirmKey);
}
isMatch(key: string) {

+ 2
- 2
src/commands/rebaseEditor.ts View File

@ -9,7 +9,7 @@ export class DisableRebaseEditorCommand extends Command {
}
execute() {
return Container.rebaseEditor.setEnabled(false);
return Container.instance.rebaseEditor.setEnabled(false);
}
}
@ -20,6 +20,6 @@ export class EnableRebaseEditorCommand extends Command {
}
execute() {
return Container.rebaseEditor.setEnabled(true);
return Container.instance.rebaseEditor.setEnabled(true);
}
}

+ 7
- 7
src/commands/remoteProviders.ts View File

@ -47,7 +47,7 @@ export class ConnectRemoteProviderCommand extends Command {
if (args?.repoPath == null) {
const repos = new Map<Repository, GitRemote<RichRemoteProvider>>();
for (const repo of await Container.git.getOrderedRepositories()) {
for (const repo of await Container.instance.git.getOrderedRepositories()) {
const remote = await repo.getRichRemote();
if (remote?.provider != null && !(await remote.provider.isConnected())) {
repos.set(repo, remote);
@ -73,18 +73,18 @@ export class ConnectRemoteProviderCommand extends Command {
} else if (args?.remote == null) {
repoPath = args.repoPath;
remote = await Container.git.getRichRemoteProvider(repoPath, { includeDisconnected: true });
remote = await Container.instance.git.getRichRemoteProvider(repoPath, { includeDisconnected: true });
if (remote == null) return false;
} else {
repoPath = args.repoPath;
remotes = await Container.git.getRemotes(repoPath);
remotes = await Container.instance.git.getRemotes(repoPath);
remote = remotes.find(r => r.id === args.remote) as GitRemote<RichRemoteProvider> | undefined;
if (!remote?.provider.hasApi()) return false;
}
const connected = await remote.provider.connect();
if (connected && !(remotes ?? (await Container.git.getRemotes(repoPath))).some(r => r.default)) {
if (connected && !(remotes ?? (await Container.instance.git.getRemotes(repoPath))).some(r => r.default)) {
await remote.setAsDefault(true);
}
return connected;
@ -135,7 +135,7 @@ export class DisconnectRemoteProviderCommand extends Command {
if (args?.repoPath == null) {
const repos = new Map<Repository, GitRemote<RichRemoteProvider>>();
for (const repo of await Container.git.getOrderedRepositories()) {
for (const repo of await Container.instance.git.getOrderedRepositories()) {
const remote = await repo.getRichRemote(true);
if (remote != null) {
repos.set(repo, remote);
@ -161,12 +161,12 @@ export class DisconnectRemoteProviderCommand extends Command {
} else if (args?.remote == null) {
repoPath = args.repoPath;
remote = await Container.git.getRichRemoteProvider(repoPath, { includeDisconnected: false });
remote = await Container.instance.git.getRichRemoteProvider(repoPath, { includeDisconnected: false });
if (remote == null) return undefined;
} else {
repoPath = args.repoPath;
remote = (await Container.git.getRemotes(repoPath)).find(r => r.id === args.remote) as
remote = (await Container.instance.git.getRemotes(repoPath)).find(r => r.id === args.remote) as
| GitRemote<RichRemoteProvider>
| undefined;
if (!remote?.provider.hasApi()) return undefined;

+ 12
- 3
src/commands/repositories.ts View File

@ -10,7 +10,10 @@ export class FetchRepositoriesCommand extends Command {
}
async execute() {
return executeGitCommand({ command: 'fetch', state: { repos: await Container.git.getOrderedRepositories() } });
return executeGitCommand({
command: 'fetch',
state: { repos: await Container.instance.git.getOrderedRepositories() },
});
}
}
@ -21,7 +24,10 @@ export class PullRepositoriesCommand extends Command {
}
async execute() {
return executeGitCommand({ command: 'pull', state: { repos: await Container.git.getOrderedRepositories() } });
return executeGitCommand({
command: 'pull',
state: { repos: await Container.instance.git.getOrderedRepositories() },
});
}
}
@ -32,6 +38,9 @@ export class PushRepositoriesCommand extends Command {
}
async execute() {
return executeGitCommand({ command: 'push', state: { repos: await Container.git.getOrderedRepositories() } });
return executeGitCommand({
command: 'push',
state: { repos: await Container.instance.git.getOrderedRepositories() },
});
}
}

+ 1
- 1
src/commands/searchCommits.ts View File

@ -50,7 +50,7 @@ export class SearchCommitsCommand extends Command {
repo: args?.repoPath,
...args?.search,
showResultsInSideBar:
Container.config.gitCommands.search.showResultsInSideBar ?? args?.showResultsInSideBar,
Container.instance.config.gitCommands.search.showResultsInSideBar ?? args?.showResultsInSideBar,
},
}));
}

+ 2
- 2
src/commands/showCommitsInView.ts View File

@ -35,12 +35,12 @@ export class ShowCommitsInViewCommand extends ActiveEditorCommand {
try {
// Check for any uncommitted changes in the range
const blame = editor.document.isDirty
? await Container.git.getBlameForRangeContents(
? await Container.instance.git.getBlameForRangeContents(
gitUri,
editor.selection,
editor.document.getText(),
)
: await Container.git.getBlameForRange(gitUri, editor.selection);
: await Container.instance.git.getBlameForRange(gitUri, editor.selection);
if (blame === undefined) {
return Messages.showFileNotUnderSourceControlWarningMessage('Unable to find commits');
}

+ 1
- 1
src/commands/showQuickBranchHistory.ts View File

@ -32,7 +32,7 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
const gitUri = uri != null ? await GitUri.fromUri(uri) : undefined;
const repoPath = args?.repoPath ?? gitUri?.repoPath ?? Container.git.getHighlanderRepoPath();
const repoPath = args?.repoPath ?? gitUri?.repoPath ?? Container.instance.git.getHighlanderRepoPath();
let ref: GitReference | 'HEAD' | undefined;
if (repoPath != null) {
if (args?.branch != null) {

+ 2
- 2
src/commands/showQuickCommit.ts View File

@ -89,7 +89,7 @@ export class ShowQuickCommitCommand extends ActiveEditorCachedCommand {
if (blameline < 0) return;
try {
const blame = await Container.git.getBlameForLine(gitUri, blameline);
const blame = await Container.instance.git.getBlameForLine(gitUri, blameline);
if (blame == null) {
void Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit');
@ -126,7 +126,7 @@ export class ShowQuickCommitCommand extends ActiveEditorCachedCommand {
}
if (args.repoLog == null) {
args.commit = await Container.git.getCommit(repoPath!, args.sha);
args.commit = await Container.instance.git.getCommit(repoPath!, args.sha);
}
}

+ 5
- 3
src/commands/showQuickCommitFile.ts View File

@ -78,7 +78,7 @@ export class ShowQuickCommitFileCommand extends ActiveEditorCachedCommand {
if (blameline < 0) return;
try {
const blame = await Container.git.getBlameForLine(gitUri, blameline);
const blame = await Container.instance.git.getBlameForLine(gitUri, blameline);
if (blame == null) {
void Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit file details');
@ -115,7 +115,9 @@ export class ShowQuickCommitFileCommand extends ActiveEditorCachedCommand {
if (args.fileLog === undefined) {
const repoPath = args.commit === undefined ? gitUri.repoPath : args.commit.repoPath;
args.commit = await Container.git.getCommitForFile(repoPath, gitUri.fsPath, { ref: args.sha });
args.commit = await Container.instance.git.getCommitForFile(repoPath, gitUri.fsPath, {
ref: args.sha,
});
if (args.commit === undefined) {
void Messages.showCommitNotFoundWarningMessage('Unable to show commit file details');
@ -134,7 +136,7 @@ export class ShowQuickCommitFileCommand extends ActiveEditorCachedCommand {
const fileName = args.commit.fileName;
if (args.commit instanceof GitBlameCommit) {
args.commit = (await Container.git.getCommit(args.commit.repoPath, args.commit.ref))!;
args.commit = (await Container.instance.git.getCommit(args.commit.repoPath, args.commit.ref))!;
}
void (await executeGitCommand({

+ 1
- 1
src/commands/showQuickFileHistory.ts View File

@ -50,7 +50,7 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand {
const gitUri = await GitUri.fromUri(uri);
if (args?.showInSideBar) {
await Container.fileHistoryView.showHistoryForUri(gitUri);
await Container.instance.fileHistoryView.showHistoryForUri(gitUri);
return;
}

+ 11
- 11
src/commands/showView.ts View File

@ -29,28 +29,28 @@ export class ShowViewCommand extends Command {
async execute(command: Commands) {
switch (command) {
case Commands.ShowBranchesView:
return Container.branchesView.show();
return Container.instance.branchesView.show();
case Commands.ShowCommitsView:
return Container.commitsView.show();
return Container.instance.commitsView.show();
case Commands.ShowContributorsView:
return Container.contributorsView.show();
return Container.instance.contributorsView.show();
case Commands.ShowFileHistoryView:
return Container.fileHistoryView.show();
return Container.instance.fileHistoryView.show();
case Commands.ShowLineHistoryView:
return Container.lineHistoryView.show();
return Container.instance.lineHistoryView.show();
case Commands.ShowRemotesView:
return Container.remotesView.show();
return Container.instance.remotesView.show();
case Commands.ShowRepositoriesView:
return Container.repositoriesView.show();
return Container.instance.repositoriesView.show();
case Commands.ShowSearchAndCompareView:
return Container.searchAndCompareView.show();
return Container.instance.searchAndCompareView.show();
case Commands.ShowStashesView:
return Container.stashesView.show();
return Container.instance.stashesView.show();
case Commands.ShowTagsView:
return Container.tagsView.show();
return Container.instance.tagsView.show();
case Commands.ShowWelcomeView:
await setContext(ContextKeys.ViewsWelcomeVisible, true);
void Container.context.globalState.update(SyncedState.WelcomeViewVisible, true);
void Container.instance.context.globalState.update(SyncedState.WelcomeViewVisible, true);
void (await commands.executeCommand('gitlens.views.welcome.focus'));
}

+ 4
- 4
src/commands/stashSave.ts View File

@ -46,9 +46,9 @@ export class StashSaveCommand extends Command {
} else if (context.type === 'scm-states') {
args = { ...args };
args.uris = context.scmResourceStates.map(s => s.resourceUri);
args.repoPath = await Container.git.getRepoPath(args.uris[0].fsPath);
args.repoPath = await Container.instance.git.getRepoPath(args.uris[0].fsPath);
const status = await Container.git.getStatusForRepo(args.repoPath);
const status = await Container.instance.git.getStatusForRepo(args.repoPath);
if (status?.computeWorkingTreeStatus().staged) {
if (!context.scmResourceStates.some(s => (s as any).resourceGroupType === ResourceGroupType.Index)) {
args.keepStaged = true;
@ -60,9 +60,9 @@ export class StashSaveCommand extends Command {
(a, b) => a.concat(b.resourceStates.map(s => s.resourceUri)),
[],
);
args.repoPath = await Container.git.getRepoPath(args.uris[0].fsPath);
args.repoPath = await Container.instance.git.getRepoPath(args.uris[0].fsPath);
const status = await Container.git.getStatusForRepo(args.repoPath);
const status = await Container.instance.git.getStatusForRepo(args.repoPath);
if (status?.computeWorkingTreeStatus().staged) {
if (!context.scmResourceGroups.some(g => g.id === 'index')) {
args.keepStaged = true;

+ 16
- 8
src/commands/switchMode.ts View File

@ -24,16 +24,17 @@ export class SwitchModeCommand extends Command {
cc.exitDetails = ` \u2014 mode=${pick.key ?? ''}`;
}
const active = Container.config.mode.active;
const active = Container.instance.config.mode.active;
if (active === pick.key) return;
// Check if we have applied any annotations and clear them if we won't be applying them again
if (active != null && active.length !== 0) {
const activeAnnotations = Container.config.modes?.[active].annotations;
const activeAnnotations = Container.instance.config.modes?.[active].annotations;
if (activeAnnotations != null) {
const newAnnotations = pick.key != null ? Container.config.modes?.[pick.key].annotations : undefined;
const newAnnotations =
pick.key != null ? Container.instance.config.modes?.[pick.key].annotations : undefined;
if (activeAnnotations !== newAnnotations) {
await Container.fileAnnotations.clearAll();
await Container.instance.fileAnnotations.clearAll();
}
}
}
@ -50,9 +51,14 @@ export class ToggleReviewModeCommand extends Command {
@log({ args: false, singleLine: true, timed: false })
async execute() {
if (Container.config.modes == null || !Object.keys(Container.config.modes).includes('review')) return;
if (
Container.instance.config.modes == null ||
!Object.keys(Container.instance.config.modes).includes('review')
) {
return;
}
const mode = Container.config.mode.active === 'review' ? undefined : 'review';
const mode = Container.instance.config.mode.active === 'review' ? undefined : 'review';
await configuration.update('mode.active', mode, ConfigurationTarget.Global);
}
}
@ -65,9 +71,11 @@ export class ToggleZenModeCommand extends Command {
@log({ args: false, singleLine: true, timed: false })
async execute() {
if (Container.config.modes == null || !Object.keys(Container.config.modes).includes('zen')) return;
if (Container.instance.config.modes == null || !Object.keys(Container.instance.config.modes).includes('zen')) {
return;
}
const mode = Container.config.mode.active === 'zen' ? undefined : 'zen';
const mode = Container.instance.config.mode.active === 'zen' ? undefined : 'zen';
await configuration.update('mode.active', mode, ConfigurationTarget.Global);
}
}

+ 1
- 1
src/commands/toggleCodeLens.ts View File

@ -9,6 +9,6 @@ export class ToggleCodeLensCommand extends Command {
}
execute() {
return Container.codeLens.toggleCodeLens();
return Container.instance.codeLens.toggleCodeLens();
}
}

+ 2
- 2
src/commands/toggleFileAnnotations.ts View File

@ -28,7 +28,7 @@ export class ClearFileAnnotationsCommand extends EditorCommand {
}
try {
void (await Container.fileAnnotations.clear(editor));
void (await Container.instance.fileAnnotations.clear(editor));
} catch (ex) {
Logger.error(ex, 'ClearFileAnnotationsCommand');
void Messages.showGenericErrorMessage('Unable to clear file annotations');
@ -123,7 +123,7 @@ async function toggleFileAnnotations
try {
args = { type: FileAnnotationType.Blame, ...(args as any) };
void (await Container.fileAnnotations.toggle(
void (await Container.instance.fileAnnotations.toggle(
editor,
args.type,
{

+ 1
- 1
src/commands/toggleLineBlame.ts View File

@ -11,7 +11,7 @@ export class ToggleLineBlameCommand extends ActiveEditorCommand {
async execute(editor: TextEditor, _uri?: Uri): Promise<void> {
try {
void (await Container.lineAnnotations.toggle(editor));
void (await Container.instance.lineAnnotations.toggle(editor));
} catch (ex) {
Logger.error(ex, 'ToggleLineBlameCommand');
void window.showErrorMessage(

+ 155
- 118
src/container.ts View File

@ -1,5 +1,5 @@
'use strict';
import { commands, ConfigurationChangeEvent, ConfigurationScope, ExtensionContext } from 'vscode';
import { commands, ConfigurationChangeEvent, ConfigurationScope, Event, EventEmitter, ExtensionContext } from 'vscode';
import { Autolinks } from './annotations/autolinks';
import { FileAnnotationController } from './annotations/fileAnnotationController';
import { LineAnnotationController } from './annotations/lineAnnotationController';
@ -42,53 +42,81 @@ import { SettingsWebview } from './webviews/settingsWebview';
import { WelcomeWebview } from './webviews/welcomeWebview';
export class Container {
private static _configsAffectedByMode: string[] | undefined;
private static _applyModeConfigurationTransformBound:
static #instance: Container | undefined;
static #proxy = new Proxy<Container>({} as Container, {
get: function (target, prop) {
// In case anyone has cached this instance
if (Container.#instance != null) return (Container.#instance as any)[prop];
// Allow access to config before we are initialized
if (prop === 'config') return configuration.get();
// debugger;
throw new Error('Container is not initialized');
},
});
static create(context: ExtensionContext, cfg: Config) {
if (Container.#instance != null) throw new Error('Container is already initialized');
Container.#instance = new Container(context, cfg);
return Container.#instance;
}
static get instance(): Container {
return Container.#instance ?? Container.#proxy;
}
private _onReady: EventEmitter<void> = new EventEmitter<void>();
get onReady(): Event<void> {
return this._onReady.event;
}
private _configsAffectedByMode: string[] | undefined;
private _applyModeConfigurationTransformBound:
| ((e: ConfigurationChangeEvent) => ConfigurationChangeEvent)
| undefined;
private static _terminalLinks: GitTerminalLinkProvider | undefined;
private _terminalLinks: GitTerminalLinkProvider | undefined;
static initialize(context: ExtensionContext, config: Config) {
private constructor(context: ExtensionContext, config: Config) {
this._context = context;
this._config = Container.applyMode(config);
this._config = this.applyMode(config);
context.subscriptions.push(configuration.onWillChange(this.onConfigurationChanging, this));
context.subscriptions.push((this._actionRunners = new ActionRunners()));
context.subscriptions.push((this._lineTracker = new GitLineTracker()));
context.subscriptions.push((this._tracker = new GitDocumentTracker()));
context.subscriptions.push((this._vsls = new VslsController()));
context.subscriptions.push((this._git = new GitService(this)));
context.subscriptions.push(new GitFileSystemProvider(this));
context.subscriptions.push((this._git = new GitService()));
context.subscriptions.push((this._actionRunners = new ActionRunners(this)));
context.subscriptions.push((this._tracker = new GitDocumentTracker(this)));
context.subscriptions.push((this._lineTracker = new GitLineTracker(this)));
context.subscriptions.push((this._keyboard = new Keyboard()));
context.subscriptions.push((this._vsls = new VslsController(this)));
context.subscriptions.push(new ViewFileDecorationProvider());
context.subscriptions.push((this._fileAnnotationController = new FileAnnotationController(this)));
context.subscriptions.push((this._lineAnnotationController = new LineAnnotationController(this)));
context.subscriptions.push((this._lineHoverController = new LineHoverController(this)));
context.subscriptions.push((this._statusBarController = new StatusBarController(this)));
context.subscriptions.push((this._codeLensController = new GitCodeLensController(this)));
// Since there is a bit of a chicken & egg problem with the DocumentTracker and the GitService, initialize the tracker once the GitService is loaded
this._tracker.initialize();
context.subscriptions.push((this._settingsWebview = new SettingsWebview(this)));
context.subscriptions.push((this._welcomeWebview = new WelcomeWebview(this)));
context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider(this)));
context.subscriptions.push((this._fileAnnotationController = new FileAnnotationController()));
context.subscriptions.push((this._lineAnnotationController = new LineAnnotationController()));
context.subscriptions.push((this._lineHoverController = new LineHoverController()));
context.subscriptions.push((this._statusBarController = new StatusBarController()));
context.subscriptions.push((this._codeLensController = new GitCodeLensController()));
context.subscriptions.push((this._keyboard = new Keyboard()));
context.subscriptions.push((this._settingsWebview = new SettingsWebview()));
context.subscriptions.push((this._welcomeWebview = new WelcomeWebview()));
context.subscriptions.push((this._repositoriesView = new RepositoriesView()));
context.subscriptions.push((this._commitsView = new CommitsView()));
context.subscriptions.push((this._fileHistoryView = new FileHistoryView()));
context.subscriptions.push((this._lineHistoryView = new LineHistoryView()));
context.subscriptions.push((this._branchesView = new BranchesView()));
context.subscriptions.push((this._remotesView = new RemotesView()));
context.subscriptions.push((this._stashesView = new StashesView()));
context.subscriptions.push((this._tagsView = new TagsView()));
context.subscriptions.push((this._contributorsView = new ContributorsView()));
context.subscriptions.push((this._searchAndCompareView = new SearchAndCompareView()));
context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider()));
context.subscriptions.push(new ViewFileDecorationProvider());
context.subscriptions.push((this._repositoriesView = new RepositoriesView(this)));
context.subscriptions.push((this._commitsView = new CommitsView(this)));
context.subscriptions.push((this._fileHistoryView = new FileHistoryView(this)));
context.subscriptions.push((this._lineHistoryView = new LineHistoryView(this)));
context.subscriptions.push((this._branchesView = new BranchesView(this)));
context.subscriptions.push((this._remotesView = new RemotesView(this)));
context.subscriptions.push((this._stashesView = new StashesView(this)));
context.subscriptions.push((this._tagsView = new TagsView(this)));
context.subscriptions.push((this._contributorsView = new ContributorsView(this)));
context.subscriptions.push((this._searchAndCompareView = new SearchAndCompareView(this)));
if (config.terminalLinks.enabled) {
context.subscriptions.push((this._terminalLinks = new GitTerminalLinkProvider()));
context.subscriptions.push((this._terminalLinks = new GitTerminalLinkProvider(this)));
}
context.subscriptions.push(
@ -96,18 +124,22 @@ export class Container {
if (!configuration.changed(e, 'terminalLinks.enabled')) return;
this._terminalLinks?.dispose();
if (Container.config.terminalLinks.enabled) {
context.subscriptions.push((this._terminalLinks = new GitTerminalLinkProvider()));
if (this.config.terminalLinks.enabled) {
context.subscriptions.push((this._terminalLinks = new GitTerminalLinkProvider(this)));
}
}),
);
}
context.subscriptions.push(new GitFileSystemProvider());
private _ready: boolean = false;
ready() {
if (this._ready) throw new Error('Container is already ready');
context.subscriptions.push(configuration.onWillChange(this.onConfigurationChanging, this));
this._ready = true;
this._onReady.fire();
}
private static onConfigurationChanging(e: ConfigurationWillChangeEvent) {
private onConfigurationChanging(e: ConfigurationWillChangeEvent) {
this._config = undefined;
if (configuration.changed(e.change, 'outputLevel')) {
@ -126,90 +158,90 @@ export class Container {
}
}
private static _actionRunners: ActionRunners;
static get actionRunners() {
private _actionRunners: ActionRunners;
get actionRunners() {
if (this._actionRunners == null) {
this._context.subscriptions.push((this._actionRunners = new ActionRunners()));
this._context.subscriptions.push((this._actionRunners = new ActionRunners(this)));
}
return this._actionRunners;
}
private static _autolinks: Autolinks;
static get autolinks() {
private _autolinks: Autolinks | undefined;
get autolinks() {
if (this._autolinks == null) {
this._context.subscriptions.push((this._autolinks = new Autolinks()));
this._context.subscriptions.push((this._autolinks = new Autolinks(this)));
}
return this._autolinks;
}
private static _codeLensController: GitCodeLensController;
static get codeLens() {
private _codeLensController: GitCodeLensController;
get codeLens() {
return this._codeLensController;
}
private static _branchesView: BranchesView | undefined;
static get branchesView() {
private _branchesView: BranchesView | undefined;
get branchesView() {
if (this._branchesView == null) {
this._context.subscriptions.push((this._branchesView = new BranchesView()));
this._context.subscriptions.push((this._branchesView = new BranchesView(this)));
}
return this._branchesView;
}
private static _commitsView: CommitsView | undefined;
static get commitsView() {
private _commitsView: CommitsView | undefined;
get commitsView() {
if (this._commitsView == null) {
this._context.subscriptions.push((this._commitsView = new CommitsView()));
this._context.subscriptions.push((this._commitsView = new CommitsView(this)));
}
return this._commitsView;
}
private static _config: Config | undefined;
static get config() {
private _config: Config | undefined;
get config() {
if (this._config == null) {
this._config = Container.applyMode(configuration.get());
this._config = this.applyMode(configuration.get());
}
return this._config;
}
private static _context: ExtensionContext;
static get context() {
private _context: ExtensionContext;
get context() {
return this._context;
}
private static _contributorsView: ContributorsView | undefined;
static get contributorsView() {
private _contributorsView: ContributorsView | undefined;
get contributorsView() {
if (this._contributorsView == null) {
this._context.subscriptions.push((this._contributorsView = new ContributorsView()));
this._context.subscriptions.push((this._contributorsView = new ContributorsView(this)));
}
return this._contributorsView;
}
private static _fileAnnotationController: FileAnnotationController;
static get fileAnnotations() {
private _fileAnnotationController: FileAnnotationController;
get fileAnnotations() {
return this._fileAnnotationController;
}
private static _fileHistoryView: FileHistoryView | undefined;
static get fileHistoryView() {
private _fileHistoryView: FileHistoryView | undefined;
get fileHistoryView() {
if (this._fileHistoryView == null) {
this._context.subscriptions.push((this._fileHistoryView = new FileHistoryView()));
this._context.subscriptions.push((this._fileHistoryView = new FileHistoryView(this)));
}
return this._fileHistoryView;
}
private static _git: GitService;
static get git() {
private _git: GitService;
get git() {
return this._git;
}
private static _github: Promise<import('./github/github').GitHubApi | undefined> | undefined;
static get github() {
private _github: Promise<import('./github/github').GitHubApi | undefined> | undefined;
get github() {
if (this._github == null) {
this._github = this._loadGitHubApi();
}
@ -217,7 +249,7 @@ export class Container {
return this._github;
}
private static async _loadGitHubApi() {
private async _loadGitHubApi() {
try {
return new (await import(/* webpackChunkName: "github" */ './github/github')).GitHubApi();
} catch (ex) {
@ -227,127 +259,132 @@ export class Container {
}
@memoize()
static get insiders() {
get insiders() {
return this._context.extension.id.endsWith('-insiders');
}
private static _keyboard: Keyboard;
static get keyboard() {
private _keyboard: Keyboard;
get keyboard() {
return this._keyboard;
}
private static _lineAnnotationController: LineAnnotationController;
static get lineAnnotations() {
private _lineAnnotationController: LineAnnotationController;
get lineAnnotations() {
return this._lineAnnotationController;
}
private static _lineHistoryView: LineHistoryView | undefined;
static get lineHistoryView() {
private _lineHistoryView: LineHistoryView | undefined;
get lineHistoryView() {
if (this._lineHistoryView == null) {
this._context.subscriptions.push((this._lineHistoryView = new LineHistoryView()));
this._context.subscriptions.push((this._lineHistoryView = new LineHistoryView(this)));
}
return this._lineHistoryView;
}
private static _lineHoverController: LineHoverController;
static get lineHovers() {
private _lineHoverController: LineHoverController;
get lineHovers() {
return this._lineHoverController;
}
private static _lineTracker: GitLineTracker;
static get lineTracker() {
private _lineTracker: GitLineTracker;
get lineTracker() {
return this._lineTracker;
}
private static _rebaseEditor: RebaseEditorProvider | undefined;
static get rebaseEditor() {
private _rebaseEditor: RebaseEditorProvider | undefined;
get rebaseEditor() {
if (this._rebaseEditor == null) {
this._context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider()));
this._context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider(this)));
}
return this._rebaseEditor;
}
private static _remotesView: RemotesView | undefined;
static get remotesView() {
private _remotesView: RemotesView | undefined;
get remotesView() {
if (this._remotesView == null) {
this._context.subscriptions.push((this._remotesView = new RemotesView()));
this._context.subscriptions.push((this._remotesView = new RemotesView(this)));
}
return this._remotesView;
}
private static _repositoriesView: RepositoriesView | undefined;
static get repositoriesView(): RepositoriesView {
private _repositoriesView: RepositoriesView | undefined;
get repositoriesView(): RepositoriesView {
if (this._repositoriesView == null) {
this._context.subscriptions.push((this._repositoriesView = new RepositoriesView()));
this._context.subscriptions.push((this._repositoriesView = new RepositoriesView(this)));
}
return this._repositoriesView;
}
private static _searchAndCompareView: SearchAndCompareView | undefined;
static get searchAndCompareView() {
private _searchAndCompareView: SearchAndCompareView | undefined;
get searchAndCompareView() {
if (this._searchAndCompareView == null) {
this._context.subscriptions.push((this._searchAndCompareView = new SearchAndCompareView()));
this._context.subscriptions.push((this._searchAndCompareView = new SearchAndCompareView(this)));
}
return this._searchAndCompareView;
}
private static _settingsWebview: SettingsWebview;
static get settingsWebview() {
private _settingsWebview: SettingsWebview;
get settingsWebview() {
return this._settingsWebview;
}
private static _stashesView: StashesView | undefined;
static get stashesView() {
private _stashesView: StashesView | undefined;
get stashesView() {
if (this._stashesView == null) {
this._context.subscriptions.push((this._stashesView = new StashesView()));
this._context.subscriptions.push((this._stashesView = new StashesView(this)));
}
return this._stashesView;
}
private static _statusBarController: StatusBarController;
static get statusBar() {
private _statusBarController: StatusBarController;
get statusBar() {
return this._statusBarController;
}
private static _tagsView: TagsView | undefined;
static get tagsView() {
private _tagsView: TagsView | undefined;
get tagsView() {
if (this._tagsView == null) {
this._context.subscriptions.push((this._tagsView = new TagsView()));
this._context.subscriptions.push((this._tagsView = new TagsView(this)));
}
return this._tagsView;
}
private static _tracker: GitDocumentTracker;
static get tracker() {
private _tracker: GitDocumentTracker;
get tracker() {
return this._tracker;
}
private static _viewCommands: ViewCommands | undefined;
static get viewCommands() {
@memoize()
get version(): string {
return this.context.extension.packageJSON.version;
}
private _viewCommands: ViewCommands | undefined;
get viewCommands() {
if (this._viewCommands == null) {
this._viewCommands = new ViewCommands();
this._viewCommands = new ViewCommands(this);
}
return this._viewCommands;
}
private static _vsls: VslsController;
static get vsls() {
private _vsls: VslsController;
get vsls() {
return this._vsls;
}
private static _welcomeWebview: WelcomeWebview;
static get welcomeWebview() {
private _welcomeWebview: WelcomeWebview;
get welcomeWebview() {
return this._welcomeWebview;
}
private static applyMode(config: Config) {
private applyMode(config: Config) {
if (!config.mode.active) return config;
const mode = config.modes?.[config.mode.active];
@ -399,7 +436,7 @@ export class Container {
return config;
}
private static applyModeConfigurationTransform(e: ConfigurationChangeEvent): ConfigurationChangeEvent {
private applyModeConfigurationTransform(e: ConfigurationChangeEvent): ConfigurationChangeEvent {
if (this._configsAffectedByMode == null) {
this._configsAffectedByMode = [
`gitlens.${configuration.name('mode')}`,

+ 33
- 37
src/extension.ts View File

@ -17,13 +17,9 @@ import { registerPartnerActionRunners } from './partners';
import { Strings, Versions } from './system';
import { ViewNode } from './views/nodes';
let _context: ExtensionContext | undefined;
export async function activate(context: ExtensionContext): Promise<GitLensApi | undefined> {
const start = process.hrtime();
_context = context;
if (context.extension.id === 'eamodio.gitlens-insiders') {
// Ensure that stable isn't also installed
const stable = extensions.getExtension('eamodio.gitlens');
@ -47,7 +43,7 @@ export async function activate(context: ExtensionContext): Promise
);
}
setKeysForSync();
setKeysForSync(context);
Logger.configure(context, configuration.get('outputLevel'), o => {
if (GitUri.is(o)) {
@ -112,13 +108,13 @@ export async function activate(context: ExtensionContext): Promise
}
Configuration.configure(context);
const cfg = configuration.get();
// await migrateSettings(context, previousVersion);
try {
await GitService.initialize();
// Try to use the same git as the built-in vscode git extension
const gitApi = await GitService.getBuiltInGitApi();
await Git.setOrFindGitPath(gitApi?.git.path ?? configuration.getAny<string | string[]>('git.path'));
} catch (ex) {
Logger.error(ex, `GitLens (v${gitlensVersion}) activate`);
void setEnabled(false);
@ -137,16 +133,16 @@ export async function activate(context: ExtensionContext): Promise
return undefined;
}
Container.initialize(context, cfg);
const container = Container.create(context, cfg);
// Signal that the container is now ready
container.ready();
registerCommands(context);
registerBuiltInActionRunners(context);
registerBuiltInActionRunners(container);
registerPartnerActionRunners(context);
const gitVersion = Git.getGitVersion();
notifyOnUnsupportedGitVersion(gitVersion);
void showWelcomeOrWhatsNew(context, gitlensVersion, previousVersion);
notifyOnUnsupportedGitVersion(Git.getGitVersion());
void showWelcomeOrWhatsNew(container, gitlensVersion, previousVersion);
void context.globalState.update(GlobalState.Version, gitlensVersion);
@ -171,7 +167,7 @@ export async function activate(context: ExtensionContext): Promise
} ${Strings.getDurationMilliseconds(start)} ms`,
);
const api = new Api();
const api = new Api(container);
return api;
}
@ -196,20 +192,20 @@ export async function setEnabled(enabled: boolean): Promise {
await Promise.all([setContext(ContextKeys.Enabled, enabled), setContext(ContextKeys.Disabled, !enabled)]);
}
export function setKeysForSync(...keys: (SyncedState | string)[]) {
return _context?.globalState?.setKeysForSync([...keys, SyncedState.Version, SyncedState.WelcomeViewVisible]);
function setKeysForSync(context: ExtensionContext, ...keys: (SyncedState | string)[]) {
return context.globalState?.setKeysForSync([...keys, SyncedState.Version, SyncedState.WelcomeViewVisible]);
}
export function notifyOnUnsupportedGitVersion(version: string) {
function notifyOnUnsupportedGitVersion(version: string) {
if (GitService.compareGitVersion('2.7.2') !== -1) return;
// If git is less than v2.7.2
void Messages.showGitVersionUnsupportedErrorMessage(version, '2.7.2');
}
function registerBuiltInActionRunners(context: ExtensionContext): void {
context.subscriptions.push(
Container.actionRunners.registerBuiltIn<CreatePullRequestActionContext>('createPullRequest', {
function registerBuiltInActionRunners(container: Container): void {
container.context.subscriptions.push(
container.actionRunners.registerBuiltIn<CreatePullRequestActionContext>('createPullRequest', {
label: ctx => `Create Pull Request on ${ctx.remote?.provider?.name ?? 'Remote'}`,
run: async ctx => {
if (ctx.type !== 'createPullRequest') return;
@ -226,7 +222,7 @@ function registerBuiltInActionRunners(context: ExtensionContext): void {
}));
},
}),
Container.actionRunners.registerBuiltIn<OpenPullRequestActionContext>('openPullRequest', {
container.actionRunners.registerBuiltIn<OpenPullRequestActionContext>('openPullRequest', {
label: ctx => `Open Pull Request on ${ctx.provider?.name ?? 'Remote'}`,
run: async ctx => {
if (ctx.type !== 'openPullRequest') return;
@ -239,31 +235,31 @@ function registerBuiltInActionRunners(context: ExtensionContext): void {
);
}
async function showWelcomeOrWhatsNew(context: ExtensionContext, version: string, previousVersion: string | undefined) {
async function showWelcomeOrWhatsNew(container: Container, version: string, previousVersion: string | undefined) {
if (previousVersion == null) {
Logger.log(`GitLens first-time install; window.focused=${window.state.focused}`);
if (Container.config.showWelcomeOnInstall === false) return;
if (container.config.showWelcomeOnInstall === false) return;
if (window.state.focused) {
await context.globalState.update(GlobalState.PendingWelcomeOnFocus, undefined);
await container.context.globalState.update(GlobalState.PendingWelcomeOnFocus, undefined);
await commands.executeCommand(Commands.ShowWelcomePage);
} else {
// Save pending on window getting focus
await context.globalState.update(GlobalState.PendingWelcomeOnFocus, true);
await container.context.globalState.update(GlobalState.PendingWelcomeOnFocus, true);
const disposable = window.onDidChangeWindowState(e => {
if (!e.focused) return;
disposable.dispose();
// If the window is now focused and we are pending the welcome, clear the pending state and show the welcome
if (context.globalState.get(GlobalState.PendingWelcomeOnFocus) === true) {
void context.globalState.update(GlobalState.PendingWelcomeOnFocus, undefined);
if (Container.config.showWelcomeOnInstall) {
if (container.context.globalState.get(GlobalState.PendingWelcomeOnFocus) === true) {
void container.context.globalState.update(GlobalState.PendingWelcomeOnFocus, undefined);
if (container.config.showWelcomeOnInstall) {
void commands.executeCommand(Commands.ShowWelcomePage);
}
}
});
context.subscriptions.push(disposable);
container.context.subscriptions.push(disposable);
}
return;
@ -284,27 +280,27 @@ async function showWelcomeOrWhatsNew(context: ExtensionContext, version: string,
return;
}
if (major !== prevMajor && Container.config.showWhatsNewAfterUpgrades) {
if (major !== prevMajor && container.config.showWhatsNewAfterUpgrades) {
if (window.state.focused) {
await context.globalState.update(GlobalState.PendingWhatsNewOnFocus, undefined);
await container.context.globalState.update(GlobalState.PendingWhatsNewOnFocus, undefined);
await Messages.showWhatsNewMessage(version);
} else {
// Save pending on window getting focus
await context.globalState.update(GlobalState.PendingWhatsNewOnFocus, true);
await container.context.globalState.update(GlobalState.PendingWhatsNewOnFocus, true);
const disposable = window.onDidChangeWindowState(e => {
if (!e.focused) return;
disposable.dispose();
// If the window is now focused and we are pending the what's new, clear the pending state and show the what's new
if (context.globalState.get(GlobalState.PendingWhatsNewOnFocus) === true) {
void context.globalState.update(GlobalState.PendingWhatsNewOnFocus, undefined);
if (Container.config.showWhatsNewAfterUpgrades) {
if (container.context.globalState.get(GlobalState.PendingWhatsNewOnFocus) === true) {
void container.context.globalState.update(GlobalState.PendingWhatsNewOnFocus, undefined);
if (container.config.showWhatsNewAfterUpgrades) {
void Messages.showWhatsNewMessage(version);
}
}
});
context.subscriptions.push(disposable);
container.context.subscriptions.push(disposable);
}
}
}

+ 22
- 15
src/git/formatters/commitFormatter.ts View File

@ -136,7 +136,8 @@ export class CommitFormatter extends Formatter {
}
private get _pullRequestDateOrAgo() {
const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle;
const dateStyle =
this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle;
return dateStyle === DateStyle.Absolute ? this._pullRequestDate : this._pullRequestDateAgo;
}
@ -145,7 +146,8 @@ export class CommitFormatter extends Formatter {
}
get agoOrDate(): string {
const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle;
const dateStyle =
this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle;
return this._padOrTruncate(
dateStyle === DateStyle.Absolute ? this._date : this._dateAgo,
this._options.tokenOptions.agoOrDate,
@ -153,7 +155,8 @@ export class CommitFormatter extends Formatter {
}
get agoOrDateShort(): string {
const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle;
const dateStyle =
this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle;
return this._padOrTruncate(
dateStyle === DateStyle.Absolute ? this._date : this._dateAgoShort,
this._options.tokenOptions.agoOrDateShort,
@ -174,7 +177,8 @@ export class CommitFormatter extends Formatter {
}
get authorAgoOrDate(): string {
const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle;
const dateStyle =
this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle;
return this._padOrTruncate(
dateStyle === DateStyle.Absolute ? this._authorDate : this._authorDateAgo,
this._options.tokenOptions.authorAgoOrDate,
@ -182,7 +186,8 @@ export class CommitFormatter extends Formatter {
}
get authorAgoOrDateShort(): string {
const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle;
const dateStyle =
this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle;
return this._padOrTruncate(
dateStyle === DateStyle.Absolute ? this._authorDate : this._authorDateAgoShort,
this._options.tokenOptions.authorAgoOrDateShort,
@ -205,7 +210,7 @@ export class CommitFormatter extends Formatter {
}
get avatar(): string | Promise<string> {
if (!this._options.markdown || !Container.config.hovers.avatars) {
if (!this._options.markdown || !Container.instance.config.hovers.avatars) {
return this._padOrTruncate(emptyStr, this._options.tokenOptions.avatar);
}
@ -228,9 +233,9 @@ export class CommitFormatter extends Formatter {
}
private async _getAvatarMarkdown(title: string, size?: number) {
size = size ?? Container.config.hovers.avatarSize;
size = size ?? Container.instance.config.hovers.avatarSize;
const avatarPromise = this._item.getAvatarUri({
defaultStyle: Container.config.defaultGravatarsStyle,
defaultStyle: Container.instance.config.defaultGravatarsStyle,
size: size,
});
return this._padOrTruncate(
@ -350,13 +355,13 @@ export class CommitFormatter extends Formatter {
provider: { id: pr.provider.id, name: pr.provider.name, domain: pr.provider.domain },
pullRequest: { id: pr.id, url: pr.url },
})} "Open Pull Request \\#${pr.id}${
Container.actionRunners.count('openPullRequest') == 1 ? ` on ${pr.provider.name}` : '...'
Container.instance.actionRunners.count('openPullRequest') == 1 ? ` on ${pr.provider.name}` : '...'
}\n${GlyphChars.Dash.repeat(2)}\n${Strings.escapeMarkdown(pr.title).replace(/"/g, '\\"')}\n${
pr.state
}, ${pr.formatDateFromNow()}")`;
} else if (pr instanceof Promises.CancellationError) {
commands += `${separator}[$(git-pull-request) PR $(loading~spin)](command:${Commands.RefreshHover} "Searching for a Pull Request (if any) that introduced this commit...")`;
} else if (pr.provider != null && Container.config.integrations.enabled) {
} else if (pr.provider != null && Container.instance.config.integrations.enabled) {
commands += `${separator}[$(plug) Connect to ${pr.provider.name}${
GlyphChars.Ellipsis
}](${ConnectRemoteProviderCommand.getMarkdownCommandArgs(pr)} "Connect to ${
@ -365,7 +370,7 @@ export class CommitFormatter extends Formatter {
}
}
if (Container.actionRunners.count('hover.commands') > 0) {
if (Container.instance.actionRunners.count('hover.commands') > 0) {
commands += `${separator}[$(organization) Team${GlyphChars.SpaceThinnest}${
GlyphChars.Ellipsis
}](${getMarkdownActionCommand<HoverCommandsActionContext>('hover.commands', {
@ -400,7 +405,8 @@ export class CommitFormatter extends Formatter {
}
get committerAgoOrDate(): string {
const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle;
const dateStyle =
this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle;
return this._padOrTruncate(
dateStyle === DateStyle.Absolute ? this._committerDate : this._committerDateAgo,
this._options.tokenOptions.committerAgoOrDate,
@ -408,7 +414,8 @@ export class CommitFormatter extends Formatter {
}
get committerAgoOrDateShort(): string {
const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle;
const dateStyle =
this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle;
return this._padOrTruncate(
dateStyle === DateStyle.Absolute ? this._committerDate : this._committerDateAgoShort,
this._options.tokenOptions.committerAgoOrDateShort,
@ -477,7 +484,7 @@ export class CommitFormatter extends Formatter {
message = this._padOrTruncate(message, this._options.tokenOptions.message);
if (this._options.messageAutolinks) {
message = Container.autolinks.linkify(
message = Container.instance.autolinks.linkify(
this._options.markdown ? Strings.escapeMarkdown(message, { quoted: true }) : message,
this._options.markdown ?? false,
this._options.remotes,
@ -507,7 +514,7 @@ export class CommitFormatter extends Formatter {
provider: { id: pr.provider.id, name: pr.provider.name, domain: pr.provider.domain },
pullRequest: { id: pr.id, url: pr.url },
})} "Open Pull Request \\#${pr.id}${
Container.actionRunners.count('openPullRequest') == 1 ? ` on ${pr.provider.name}` : '...'
Container.instance.actionRunners.count('openPullRequest') == 1 ? ` on ${pr.provider.name}` : '...'
}\n${GlyphChars.Dash.repeat(2)}\n${Strings.escapeMarkdown(pr.title).replace(/"/g, '\\"')}\n${
pr.state
}, ${pr.formatDateFromNow()}")`;

+ 4
- 4
src/git/fsProvider.ts View File

@ -33,7 +33,7 @@ export class GitFileSystemProvider implements FileSystemProvider, Disposable {
private readonly _disposable: Disposable;
private readonly _searchTreeMap = new Map<string, Promise<TernarySearchTree<string, GitTree>>>();
constructor() {
constructor(private readonly container: Container) {
this._disposable = Disposable.from(
workspace.registerFileSystemProvider(DocumentSchemes.GitLens, this, {
isCaseSensitive: true,
@ -83,7 +83,7 @@ export class GitFileSystemProvider implements FileSystemProvider, Disposable {
if (ref === GitRevision.deletedOrMissing) return emptyArray;
const buffer = await Container.git.getVersionedFileBuffer(repoPath, path, ref);
const buffer = await this.container.git.getVersionedFileBuffer(repoPath, path, ref);
if (buffer === undefined) return emptyArray;
return buffer;
@ -125,7 +125,7 @@ export class GitFileSystemProvider implements FileSystemProvider, Disposable {
};
}
treeItem = await Container.git.getTreeFileForRevision(repoPath, path, ref);
treeItem = await this.container.git.getTreeFileForRevision(repoPath, path, ref);
}
if (treeItem === undefined) {
@ -154,7 +154,7 @@ export class GitFileSystemProvider implements FileSystemProvider, Disposable {
private async createSearchTree(ref: string, repoPath: string) {
const searchTree = TernarySearchTree.forPaths<GitTree>();
const trees = await Container.git.getTreeForRevision(repoPath, ref);
const trees = await this.container.git.getTreeForRevision(repoPath, ref);
// Add a fake root folder so that searches will work
searchTree.set('~', { commitSha: '', path: '~', size: 0, type: 'tree' });

+ 7
- 3
src/git/git.ts View File

@ -75,9 +75,9 @@ export interface GitCommandOptions extends RunOptions
const pendingCommands = new Map<string, Promise<string | Buffer>>();
export async function git<TOut extends string | Buffer>(options: GitCommandOptions, ...args: any[]): Promise<TOut> {
if (Container.vsls.isMaybeGuest) {
if (Container.instance.vsls.isMaybeGuest) {
if (options.local !== true) {
const guest = await Container.vsls.guest();
const guest = await Container.instance.vsls.guest();
if (guest !== undefined) {
return guest.git<TOut>(options, ...args);
}
@ -1396,7 +1396,11 @@ export namespace Git {
return git<string>({ cwd: repoPath, errors: GitErrorHandling.Ignore }, 'show-ref', '--tags');
}
export function stash__apply(repoPath: string, stashName: string, deleteAfter: boolean) {
export function stash__apply(
repoPath: string,
stashName: string,
deleteAfter: boolean,
): Promise<string | undefined> {
if (!stashName) return Promise.resolve(undefined);
return git<string>({ cwd: repoPath }, 'stash', deleteAfter ? 'pop' : 'apply', stashName);
}

+ 72
- 77
src/git/gitService.ts View File

@ -137,6 +137,7 @@ export class GitService implements Disposable {
private readonly _disposable: Disposable;
private readonly _repositoryTree: TernarySearchTree<string, Repository>;
private _repositoriesLoadingPromise: Promise<void> | undefined;
private _repositoriesLoadingPromiseResolver: (() => void) | undefined;
private readonly _branchesCache = new Map<string, Promise<GitBranch[]>>();
private readonly _contributorsCache = new Map<string, Promise<GitContributor[]>>();
@ -148,10 +149,11 @@ export class GitService implements Disposable {
private readonly _trackedCache = new Map<string, boolean | Promise<boolean>>();
private readonly _userMapCache = new Map<string, GitUser | null>();
constructor() {
constructor(private readonly container: Container) {
this._repositoryTree = TernarySearchTree.forPaths();
this._disposable = Disposable.from(
container.onReady(this.onReady, this),
window.onDidChangeWindowState(this.onWindowStateChanged, this),
workspace.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged, this),
configuration.onDidChange(this.onConfigurationChanged, this),
@ -163,9 +165,10 @@ export class GitService implements Disposable {
void this.updateContext(this._repositoryTree);
}),
);
this.onConfigurationChanged();
this._repositoriesLoadingPromise = this.onWorkspaceFoldersChanged();
this._repositoriesLoadingPromise = new Promise(resolve => (this._repositoriesLoadingPromiseResolver = resolve));
this.onConfigurationChanged();
}
dispose() {
@ -174,24 +177,16 @@ export class GitService implements Disposable {
this._disposable.dispose();
}
@log()
static async initialize(): Promise<void> {
// Try to use the same git as the built-in vscode git extension
let gitPath;
const gitApi = await GitService.getBuiltInGitApi();
if (gitApi != null) {
gitPath = gitApi.git.path;
}
await Git.setOrFindGitPath(gitPath ?? configuration.getAny<string | string[]>('git.path'));
private onReady() {
this.onWorkspaceFoldersChanged().finally(() => this._repositoriesLoadingPromiseResolver!());
}
get readonly() {
return Container.vsls.readonly;
return this.container.vsls.readonly;
}
get useCaching() {
return Container.config.advanced.caching.enabled;
return this.container.config.advanced.caching.enabled;
}
private onAnyRepositoryChanged(repo: Repository, e: RepositoryChangeEvent) {
@ -287,8 +282,8 @@ export class GitService implements Disposable {
if (scheme !== DocumentSchemes.File && scheme !== DocumentSchemes.Vsls) continue;
if (scheme === DocumentSchemes.Vsls) {
if (Container.vsls.isMaybeGuest) {
const guest = await Container.vsls.guest();
if (this.container.vsls.isMaybeGuest) {
const guest = await this.container.vsls.guest();
if (guest != null) {
const repositories = await guest.getRepositoriesInFolder(
f,
@ -859,7 +854,7 @@ export class GitService implements Disposable {
let repoPath;
if (editor != null) {
const doc = await Container.tracker.getOrAdd(editor.document.uri);
const doc = await this.container.tracker.getOrAdd(editor.document.uri);
if (doc != null) {
repoPath = doc.uri.repoPath;
}
@ -888,7 +883,7 @@ export class GitService implements Disposable {
key += `:${uri.sha}`;
}
const doc = await Container.tracker.getOrAdd(uri);
const doc = await this.container.tracker.getOrAdd(uri);
if (this.useCaching) {
if (doc.state != null) {
const cachedBlame = doc.state.get<CachedBlame>(key);
@ -934,8 +929,8 @@ export class GitService implements Disposable {
try {
const data = await Git.blame(root, file, uri.sha, {
args: Container.config.advanced.blame.customArguments,
ignoreWhitespace: Container.config.blame.ignoreWhitespace,
args: this.container.config.advanced.blame.customArguments,
ignoreWhitespace: this.container.config.blame.ignoreWhitespace,
});
const blame = GitBlameParser.parse(data, root, file, await this.getCurrentUser(root));
return blame;
@ -970,7 +965,7 @@ export class GitService implements Disposable {
const key = `blame:${Strings.sha1(contents)}`;
const doc = await Container.tracker.getOrAdd(uri);
const doc = await this.container.tracker.getOrAdd(uri);
if (this.useCaching) {
if (doc.state != null) {
const cachedBlame = doc.state.get<CachedBlame>(key);
@ -1017,9 +1012,9 @@ export class GitService implements Disposable {
try {
const data = await Git.blame__contents(root, file, contents, {
args: Container.config.advanced.blame.customArguments,
args: this.container.config.advanced.blame.customArguments,
correlationKey: `:${key}`,
ignoreWhitespace: Container.config.blame.ignoreWhitespace,
ignoreWhitespace: this.container.config.blame.ignoreWhitespace,
});
const blame = GitBlameParser.parse(data, root, file, await this.getCurrentUser(root));
return blame;
@ -1075,8 +1070,8 @@ export class GitService implements Disposable {
try {
const data = await Git.blame(uri.repoPath, fileName, uri.sha, {
args: Container.config.advanced.blame.customArguments,
ignoreWhitespace: Container.config.blame.ignoreWhitespace,
args: this.container.config.advanced.blame.customArguments,
ignoreWhitespace: this.container.config.blame.ignoreWhitespace,
startLine: lineToBlame,
endLine: lineToBlame,
});
@ -1130,8 +1125,8 @@ export class GitService implements Disposable {
try {
const data = await Git.blame__contents(uri.repoPath, fileName, contents, {
args: Container.config.advanced.blame.customArguments,
ignoreWhitespace: Container.config.blame.ignoreWhitespace,
args: this.container.config.advanced.blame.customArguments,
ignoreWhitespace: this.container.config.blame.ignoreWhitespace,
startLine: lineToBlame,
endLine: lineToBlame,
});
@ -1227,14 +1222,14 @@ export class GitService implements Disposable {
let [branch] = await this.getBranches(repoPath, { filter: b => b.current });
if (branch != null) return branch;
const data = await Git.rev_parse__currentBranch(repoPath, Container.config.advanced.commitOrdering);
const data = await Git.rev_parse__currentBranch(repoPath, this.container.config.advanced.commitOrdering);
if (data == null) return undefined;
const [name, upstream] = data[0].split('\n');
if (GitBranch.isDetached(name)) {
const [rebaseStatus, committerDate] = await Promise.all([
this.getRebaseStatus(repoPath),
Git.log__recent_committerdate(repoPath, Container.config.advanced.commitOrdering),
Git.log__recent_committerdate(repoPath, this.container.config.advanced.commitOrdering),
]);
branch = new GitBranch(
@ -1316,13 +1311,13 @@ export class GitService implements Disposable {
const data = await Git.rev_parse__currentBranch(
repoPath!,
Container.config.advanced.commitOrdering,
this.container.config.advanced.commitOrdering,
);
if (data != null) {
const [name, upstream] = data[0].split('\n');
const [rebaseStatus, committerDate] = await Promise.all([
GitBranch.isDetached(name) ? this.getRebaseStatus(repoPath!) : undefined,
Git.log__recent_committerdate(repoPath!, Container.config.advanced.commitOrdering),
Git.log__recent_committerdate(repoPath!, this.container.config.advanced.commitOrdering),
]);
current = new GitBranch(
@ -1537,7 +1532,7 @@ export class GitService implements Disposable {
async getOldestUnpushedRefForFile(repoPath: string, fileName: string): Promise<string | undefined> {
const data = await Git.log__file(repoPath, fileName, '@{push}..', {
format: 'refs',
ordering: Container.config.advanced.commitOrdering,
ordering: this.container.config.advanced.commitOrdering,
renames: true,
});
if (data == null || data.length === 0) return undefined;
@ -1690,7 +1685,7 @@ export class GitService implements Disposable {
key += `:${ref2}`;
}
const doc = await Container.tracker.getOrAdd(uri);
const doc = await this.container.tracker.getOrAdd(uri);
if (this.useCaching) {
if (doc.state != null) {
const cachedDiff = doc.state.get<CachedDiff>(key);
@ -1748,7 +1743,7 @@ export class GitService implements Disposable {
// let data;
// if (ref2 == null && ref1 != null && !GitRevision.isUncommittedStaged(ref1)) {
// data = await Git.show__diff(root, file, ref1, originalFileName, {
// similarityThreshold: Container.config.advanced.similarityThreshold,
// similarityThreshold: this.container.config.advanced.similarityThreshold,
// });
// } else {
const data = await Git.diff(root, file, ref1, ref2, {
@ -1756,7 +1751,7 @@ export class GitService implements Disposable {
filters: ['M'],
linesOfContext: 0,
renames: true,
similarityThreshold: Container.config.advanced.similarityThreshold,
similarityThreshold: this.container.config.advanced.similarityThreshold,
});
// }
@ -1796,7 +1791,7 @@ export class GitService implements Disposable {
const key = `diff:${Strings.sha1(contents)}`;
const doc = await Container.tracker.getOrAdd(uri);
const doc = await this.container.tracker.getOrAdd(uri);
if (this.useCaching) {
if (doc.state != null) {
const cachedDiff = doc.state.get<CachedDiff>(key);
@ -1854,7 +1849,7 @@ export class GitService implements Disposable {
const data = await Git.diff__contents(root, file, ref, contents, {
...options,
filters: ['M'],
similarityThreshold: Container.config.advanced.similarityThreshold,
similarityThreshold: this.container.config.advanced.similarityThreshold,
});
const diff = GitDiffParser.parse(data);
@ -1909,7 +1904,7 @@ export class GitService implements Disposable {
): Promise<GitFile[] | undefined> {
try {
const data = await Git.diff__name_status(repoPath, ref1, ref2, {
similarityThreshold: Container.config.advanced.similarityThreshold,
similarityThreshold: this.container.config.advanced.similarityThreshold,
...options,
});
const files = GitDiffParser.parseNameStatus(data, repoPath);
@ -1949,15 +1944,15 @@ export class GitService implements Disposable {
since?: string;
} = {},
): Promise<GitLog | undefined> {
const limit = options.limit ?? Container.config.advanced.maxListItems ?? 0;
const limit = options.limit ?? this.container.config.advanced.maxListItems ?? 0;
try {
const data = await Git.log(repoPath, ref, {
...options,
limit: limit,
merges: options.merges == null ? true : options.merges,
ordering: options.ordering ?? Container.config.advanced.commitOrdering,
similarityThreshold: Container.config.advanced.similarityThreshold,
ordering: options.ordering ?? this.container.config.advanced.commitOrdering,
similarityThreshold: this.container.config.advanced.similarityThreshold,
});
const log = GitLogParser.parse(
data,
@ -2001,7 +1996,7 @@ export class GitService implements Disposable {
since?: string;
} = {},
): Promise<Set<string> | undefined> {
const limit = options.limit ?? Container.config.advanced.maxListItems ?? 0;
const limit = options.limit ?? this.container.config.advanced.maxListItems ?? 0;
try {
const data = await Git.log(repoPath, ref, {
@ -2010,9 +2005,9 @@ export class GitService implements Disposable {
limit: limit,
merges: options.merges == null ? true : options.merges,
reverse: options.reverse,
similarityThreshold: Container.config.advanced.similarityThreshold,
similarityThreshold: this.container.config.advanced.similarityThreshold,
since: options.since,
ordering: options.ordering ?? Container.config.advanced.commitOrdering,
ordering: options.ordering ?? this.container.config.advanced.commitOrdering,
});
const commits = GitLogParser.parseRefsOnly(data);
return new Set(commits);
@ -2040,7 +2035,7 @@ export class GitService implements Disposable {
return log;
}
moreLimit = moreLimit ?? Container.config.advanced.maxSearchItems ?? 0;
moreLimit = moreLimit ?? this.container.config.advanced.maxSearchItems ?? 0;
// If the log is for a range, then just get everything prior + more
if (GitRevision.isRange(log.sha)) {
@ -2102,8 +2097,8 @@ export class GitService implements Disposable {
search = { matchAll: false, matchCase: false, matchRegex: true, ...search };
try {
const limit = options.limit ?? Container.config.advanced.maxSearchItems ?? 0;
const similarityThreshold = Container.config.advanced.similarityThreshold;
const limit = options.limit ?? this.container.config.advanced.maxSearchItems ?? 0;
const similarityThreshold = this.container.config.advanced.similarityThreshold;
const operations = SearchPattern.parseSearchOperations(search.pattern);
@ -2175,7 +2170,7 @@ export class GitService implements Disposable {
}
const data = await Git.log__search(repoPath, args, {
ordering: Container.config.advanced.commitOrdering,
ordering: this.container.config.advanced.commitOrdering,
...options,
limit: limit,
useShow: useShow,
@ -2212,7 +2207,7 @@ export class GitService implements Disposable {
options: { limit?: number; ordering?: string | null },
): (limit: number | undefined) => Promise<GitLog> {
return async (limit: number | undefined) => {
limit = limit ?? Container.config.advanced.maxSearchItems ?? 0;
limit = limit ?? this.container.config.advanced.maxSearchItems ?? 0;
const moreLog = await this.getLogForSearch(log.repoPath, search, {
...options,
@ -2279,7 +2274,7 @@ export class GitService implements Disposable {
options = { reverse: false, ...options };
if (options.renames == null) {
options.renames = Container.config.advanced.fileHistoryFollowsRenames;
options.renames = this.container.config.advanced.fileHistoryFollowsRenames;
}
let key = 'log';
@ -2288,13 +2283,13 @@ export class GitService implements Disposable {
}
if (options.all == null) {
options.all = Container.config.advanced.fileHistoryShowAllBranches;
options.all = this.container.config.advanced.fileHistoryShowAllBranches;
}
if (options.all) {
key += ':all';
}
options.limit = options.limit == null ? Container.config.advanced.maxListItems || 0 : options.limit;
options.limit = options.limit == null ? this.container.config.advanced.maxListItems || 0 : options.limit;
if (options.limit) {
key += `:n${options.limit}`;
}
@ -2315,7 +2310,7 @@ export class GitService implements Disposable {
key += `:skip${options.skip}`;
}
const doc = await Container.tracker.getOrAdd(GitUri.fromFile(fileName, repoPath!, options.ref));
const doc = await this.container.tracker.getOrAdd(GitUri.fromFile(fileName, repoPath!, options.ref));
if (this.useCaching && options.range == null) {
if (doc.state != null) {
const cachedLog = doc.state.get<CachedLog>(key);
@ -2437,7 +2432,7 @@ export class GitService implements Disposable {
}
const data = await Git.log__file(root, file, ref, {
ordering: Container.config.advanced.commitOrdering,
ordering: this.container.config.advanced.commitOrdering,
...options,
firstParent: options.renames,
startLine: range == null ? undefined : range.start.line + 1,
@ -2506,7 +2501,7 @@ export class GitService implements Disposable {
return log;
}
moreLimit = moreLimit ?? Container.config.advanced.maxSearchItems ?? 0;
moreLimit = moreLimit ?? this.container.config.advanced.maxSearchItems ?? 0;
const ref = Iterables.last(log.commits.values())?.ref;
const moreLog = await this.getLogForFile(log.repoPath, fileName, {
@ -2768,7 +2763,7 @@ export class GitService implements Disposable {
filters: filters,
format: 'simple',
limit: skip + 1,
ordering: Container.config.advanced.commitOrdering,
ordering: this.container.config.advanced.commitOrdering,
reverse: true,
// startLine: editorLine != null ? editorLine + 1 : undefined,
});
@ -2781,7 +2776,7 @@ export class GitService implements Disposable {
filters: ['R', 'C'],
format: 'simple',
limit: 1,
ordering: Container.config.advanced.commitOrdering,
ordering: this.container.config.advanced.commitOrdering,
// startLine: editorLine != null ? editorLine + 1 : undefined
});
if (data == null || data.length === 0) {
@ -3020,7 +3015,7 @@ export class GitService implements Disposable {
firstParent: firstParent,
format: 'simple',
limit: skip + 2,
ordering: Container.config.advanced.commitOrdering,
ordering: this.container.config.advanced.commitOrdering,
startLine: editorLine != null ? editorLine + 1 : undefined,
});
} catch (ex) {
@ -3035,7 +3030,7 @@ export class GitService implements Disposable {
}
ref = await Git.log__file_recent(repoPath, fileName, {
ordering: Container.config.advanced.commitOrdering,
ordering: this.container.config.advanced.commitOrdering,
});
return GitUri.fromFile(fileName, repoPath, ref ?? GitRevision.deletedOrMissing);
}
@ -3175,11 +3170,11 @@ export class GitService implements Disposable {
): Promise<GitReflog | undefined> {
const cc = Logger.getCorrelationContext();
limit = limit ?? Container.config.advanced.maxListItems ?? 0;
limit = limit ?? this.container.config.advanced.maxListItems ?? 0;
try {
// Pass a much larger limit to reflog, because we aggregate the data and we won't know how many lines we'll need
const data = await Git.reflog(repoPath, {
ordering: Container.config.advanced.commitOrdering,
ordering: this.container.config.advanced.commitOrdering,
...options,
limit: limit * 100,
});
@ -3202,7 +3197,7 @@ export class GitService implements Disposable {
options: { all?: boolean; branch?: string; limit?: number; ordering?: string | null; skip?: number },
): (limit: number) => Promise<GitReflog> {
return async (limit: number | undefined) => {
limit = limit ?? Container.config.advanced.maxSearchItems ?? 0;
limit = limit ?? this.container.config.advanced.maxSearchItems ?? 0;
const moreLog = await this.getIncomingActivity(reflog.repoPath, {
...options,
@ -3512,7 +3507,7 @@ export class GitService implements Disposable {
@gate(() => '')
private async ensureProperWorkspaceCasing(repoPath: string, filePath: string) {
if (Container.config.advanced.messages.suppressImproperWorkspaceCasingWarning) return;
if (this.container.config.advanced.messages.suppressImproperWorkspaceCasingWarning) return;
filePath = filePath.replace(/\\/g, '/');
@ -3633,7 +3628,7 @@ export class GitService implements Disposable {
): Repository | undefined {
let repo = repositoryTree.findSubstr(path);
// If we can't find the repo and we are a guest, check if we are a "root" workspace
if (repo == null && isVslsScheme !== false && Container.vsls.isMaybeGuest) {
if (repo == null && isVslsScheme !== false && this.container.vsls.isMaybeGuest) {
if (!vslsUriPrefixRegex.test(path)) {
path = Strings.normalizePath(path);
const vslsPath = `/~0${path.startsWith(slash) ? path : `/${path}`}`;
@ -3670,7 +3665,7 @@ export class GitService implements Disposable {
let stash = this.useCaching ? this._stashesCache.get(repoPath) : undefined;
if (stash === undefined) {
const data = await Git.stash__list(repoPath, {
similarityThreshold: Container.config.advanced.similarityThreshold,
similarityThreshold: this.container.config.advanced.similarityThreshold,
});
stash = GitStashParser.parse(data, repoPath);
@ -3691,7 +3686,7 @@ export class GitService implements Disposable {
const porcelainVersion = Git.validateVersion(2, 11) ? 2 : 1;
const data = await Git.status__file(repoPath, fileName, porcelainVersion, {
similarityThreshold: Container.config.advanced.similarityThreshold,
similarityThreshold: this.container.config.advanced.similarityThreshold,
});
const status = GitStatusParser.parse(data, repoPath, porcelainVersion);
if (status == null || !status.files.length) return undefined;
@ -3704,7 +3699,7 @@ export class GitService implements Disposable {
const porcelainVersion = Git.validateVersion(2, 11) ? 2 : 1;
const data = await Git.status__file(repoPath, path, porcelainVersion, {
similarityThreshold: Container.config.advanced.similarityThreshold,
similarityThreshold: this.container.config.advanced.similarityThreshold,
});
const status = GitStatusParser.parse(data, repoPath, porcelainVersion);
if (status == null || !status.files.length) return [];
@ -3719,7 +3714,7 @@ export class GitService implements Disposable {
const porcelainVersion = Git.validateVersion(2, 11) ? 2 : 1;
const data = await Git.status(repoPath, porcelainVersion, {
similarityThreshold: Container.config.advanced.similarityThreshold,
similarityThreshold: this.container.config.advanced.similarityThreshold,
});
const status = GitStatusParser.parse(data, repoPath, porcelainVersion);
@ -3857,8 +3852,8 @@ export class GitService implements Disposable {
// TODO: Add caching
// Get the most recent commit for this file name
ref = await Git.log__file_recent(repoPath, fileName, {
ordering: Container.config.advanced.commitOrdering,
similarityThreshold: Container.config.advanced.similarityThreshold,
ordering: this.container.config.advanced.commitOrdering,
similarityThreshold: this.container.config.advanced.similarityThreshold,
});
if (ref == null) return undefined;
@ -3867,7 +3862,7 @@ export class GitService implements Disposable {
filters: ['R', 'C', 'D'],
format: 'simple',
limit: 1,
ordering: Container.config.advanced.commitOrdering,
ordering: this.container.config.advanced.commitOrdering,
});
if (data == null || data.length === 0) break;
@ -3937,7 +3932,7 @@ export class GitService implements Disposable {
editor = editor ?? window.activeTextEditor;
if (editor == null) return false;
const doc = await Container.tracker.getOrAdd(editor.document.uri);
const doc = await this.container.tracker.getOrAdd(editor.document.uri);
return repoPath === doc?.uri.repoPath;
}
@ -4053,7 +4048,7 @@ export class GitService implements Disposable {
if (!options.tool) {
const cc = Logger.getCorrelationContext();
options.tool = Container.config.advanced.externalDiffTool || (await this.getDiffTool(repoPath));
options.tool = this.container.config.advanced.externalDiffTool || (await this.getDiffTool(repoPath));
if (options.tool == null) throw new Error('No diff tool found');
Logger.log(cc, `Using tool=${options.tool}`);
@ -4089,7 +4084,7 @@ export class GitService implements Disposable {
if (!tool) {
const cc = Logger.getCorrelationContext();
tool = Container.config.advanced.externalDirectoryDiffTool || (await this.getDiffTool(repoPath));
tool = this.container.config.advanced.externalDirectoryDiffTool || (await this.getDiffTool(repoPath));
if (tool == null) throw new Error('No diff tool found');
Logger.log(cc, `Using tool=${tool}`);
@ -4154,7 +4149,7 @@ export class GitService implements Disposable {
repoPath,
blob,
ref,
Container.config.advanced.commitOrdering,
this.container.config.advanced.commitOrdering,
fileName,
);
if (options?.timeout != null) {
@ -4165,7 +4160,7 @@ export class GitService implements Disposable {
}
@log()
validateBranchOrTagName(ref: string, repoPath?: string): Promise<boolean> {
validateBranchOrTagName(repoPath: string, ref: string): Promise<boolean> {
return Git.check_ref_format(ref, repoPath);
}

+ 5
- 5
src/git/gitUri.ts View File

@ -215,7 +215,7 @@ export class GitUri extends (Uri as any as UriEx) {
static file(path: string, useVslsScheme?: boolean) {
const uri = Uri.file(path);
if (Container.vsls.isMaybeGuest && useVslsScheme !== false) {
if (Container.instance.vsls.isMaybeGuest && useVslsScheme !== false) {
return uri.with({ scheme: DocumentSchemes.Vsls });
}
@ -257,7 +257,7 @@ export class GitUri extends (Uri as any as UriEx) {
static async fromUri(uri: Uri): Promise<GitUri> {
if (GitUri.is(uri)) return uri;
if (!Container.git.isTrackable(uri)) return new GitUri(uri);
if (!Container.instance.git.isTrackable(uri)) return new GitUri(uri);
if (uri.scheme === DocumentSchemes.GitLens) return new GitUri(uri);
@ -266,7 +266,7 @@ export class GitUri extends (Uri as any as UriEx) {
try {
const data: { path: string; ref: string } = JSON.parse(uri.query);
const repoPath = await Container.git.getRepoPath(data.path);
const repoPath = await Container.instance.git.getRepoPath(data.path);
let ref;
switch (data.ref) {
@ -309,7 +309,7 @@ export class GitUri extends (Uri as any as UriEx) {
if (repoPath.endsWith(data.fileName)) {
repoPath = repoPath.substr(0, repoPath.length - data.fileName.length - 1);
} else {
repoPath = (await Container.git.getRepoPath(uri.fsPath))!;
repoPath = (await Container.instance.git.getRepoPath(uri.fsPath))!;
}
const commitish: GitCommitish = {
@ -321,7 +321,7 @@ export class GitUri extends (Uri as any as UriEx) {
} catch {}
}
return new GitUri(uri, await Container.git.getRepoPath(uri));
return new GitUri(uri, await Container.instance.git.getRepoPath(uri));
}
static getDirectory(fileName: string, relativeTo?: string): string {

+ 6
- 6
src/git/models/branch.ts View File

@ -180,7 +180,7 @@ export class GitBranch implements GitBranchReference {
const remote = await this.getRemote();
if (remote == null) return undefined;
return Container.git.getPullRequestForBranch(this.getNameWithoutRemote(), remote, options);
return Container.instance.git.getPullRequestForBranch(this.getNameWithoutRemote(), remote, options);
}
@memoize()
@ -205,7 +205,7 @@ export class GitBranch implements GitBranchReference {
const remoteName = this.getRemoteName();
if (remoteName == null) return undefined;
const remotes = await Container.git.getRemotes(this.repoPath);
const remotes = await Container.instance.git.getRemotes(this.repoPath);
if (remotes.length === 0) return undefined;
return remotes.find(r => r.name === remoteName);
@ -231,7 +231,7 @@ export class GitBranch implements GitBranchReference {
return GitBranchStatus.UpToDate;
}
const remotes = await Container.git.getRemotes(this.repoPath);
const remotes = await Container.instance.git.getRemotes(this.repoPath);
if (remotes.length > 0) return GitBranchStatus.Unpublished;
return GitBranchStatus.Local;
@ -250,16 +250,16 @@ export class GitBranch implements GitBranchReference {
}
get starred() {
const starred = Container.context.workspaceState.get<Starred>(WorkspaceState.StarredBranches);
const starred = Container.instance.context.workspaceState.get<Starred>(WorkspaceState.StarredBranches);
return starred !== undefined && starred[this.id] === true;
}
async star() {
await (await Container.git.getRepository(this.repoPath))?.star(this);
await (await Container.instance.git.getRepository(this.repoPath))?.star(this);
}
async unstar() {
await (await Container.git.getRepository(this.repoPath))?.unstar(this);
await (await Container.instance.git.getRepository(this.repoPath))?.unstar(this);
}
static formatDetached(sha: string): string {

+ 4
- 4
src/git/models/commit.ts View File

@ -148,10 +148,10 @@ export abstract class GitCommit implements GitRevisionReference {
@memoize()
async getAssociatedPullRequest(options?: { timeout?: number }): Promise<PullRequest | undefined> {
const remote = await Container.git.getRichRemoteProvider(this.repoPath);
const remote = await Container.instance.git.getRichRemoteProvider(this.repoPath);
if (remote?.provider == null) return undefined;
return Container.git.getPullRequestForCommit(this.ref, remote, options);
return Container.instance.git.getPullRequestForCommit(this.ref, remote, options);
}
@memoize<GitCommit['getPreviousLineDiffUris']>(
@ -160,14 +160,14 @@ export abstract class GitCommit implements GitRevisionReference {
getPreviousLineDiffUris(uri: Uri, editorLine: number, ref: string | undefined) {
if (!this.isFile) return Promise.resolve(undefined);
return Container.git.getPreviousLineDiffUris(this.repoPath, uri, editorLine, ref);
return Container.instance.git.getPreviousLineDiffUris(this.repoPath, uri, editorLine, ref);
}
@memoize()
getWorkingUri(): Promise<Uri | undefined> {
if (!this.isFile) return Promise.resolve(undefined);
return Container.git.getWorkingUri(this.repoPath, this.uri);
return Container.instance.git.getWorkingUri(this.repoPath, this.uri);
}
@memoize()

+ 1
- 1
src/git/models/models.ts View File

@ -77,7 +77,7 @@ export namespace GitRevision {
if (!force && !isShaLike(ref)) return ref;
// Don't allow shas to be shortened to less than 5 characters
const len = Math.max(5, Container.config.advanced.abbreviatedShaLength);
const len = Math.max(5, Container.instance.config.advanced.abbreviatedShaLength);
// If we have a suffix, append it
const match = shaShortenRegex.exec(ref);

+ 7
- 4
src/git/models/remote.ts View File

@ -59,7 +59,7 @@ export class GitRemote
) {}
get default() {
const defaultRemote = Container.context.workspaceState.get<string>(WorkspaceState.DefaultRemote);
const defaultRemote = Container.instance.context.workspaceState.get<string>(WorkspaceState.DefaultRemote);
return this.id === defaultRemote;
}
@ -79,12 +79,15 @@ export class GitRemote
}
async setAsDefault(state: boolean = true, updateViews: boolean = true) {
void (await Container.context.workspaceState.update(WorkspaceState.DefaultRemote, state ? this.id : undefined));
void (await Container.instance.context.workspaceState.update(
WorkspaceState.DefaultRemote,
state ? this.id : undefined,
));
// TODO@eamodio this is UGLY
if (updateViews) {
void (await Container.remotesView.refresh());
void (await Container.repositoriesView.refresh());
void (await Container.instance.remotesView.refresh());
void (await Container.instance.repositoriesView.refresh());
}
}
}

+ 36
- 30
src/git/models/repository.ts View File

@ -157,14 +157,14 @@ export class Repository implements Disposable {
}
if (short) {
return formatter.format(Container.config.defaultDateShortFormat ?? 'MMM D, YYYY');
return formatter.format(Container.instance.config.defaultDateShortFormat ?? 'MMM D, YYYY');
}
let format =
Container.config.defaultDateFormat ??
`dddd, MMMM Do, YYYY [at] ${Container.config.defaultTimeFormat ?? 'h:mma'}`;
Container.instance.config.defaultDateFormat ??
`dddd, MMMM Do, YYYY [at] ${Container.instance.config.defaultTimeFormat ?? 'h:mma'}`;
if (!/[hHm]/.test(format)) {
format += ` [at] ${Container.config.defaultTimeFormat ?? 'h:mma'}`;
format += ` [at] ${Container.instance.config.defaultTimeFormat ?? 'h:mma'}`;
}
return formatter.format(format);
}
@ -298,6 +298,10 @@ export class Repository implements Disposable {
this._disposable.dispose();
}
get uri(): Uri {
return Uri.file(this.path);
}
private _supportsChangeEvents: boolean = true;
get supportsChangeEvents(): boolean {
return this._supportsChangeEvents;
@ -524,7 +528,7 @@ export class Repository implements Disposable {
options: { all?: boolean; branch?: GitBranchReference; prune?: boolean; pull?: boolean; remote?: string } = {},
) {
try {
void (await Container.git.fetch(this.path, options));
void (await Container.instance.git.fetch(this.path, options));
this.fireChange(RepositoryChange.Unknown);
} catch (ex) {
@ -540,7 +544,7 @@ export class Repository implements Disposable {
}
if (this._branch == null || !this.supportsChangeEvents) {
this._branch = Container.git.getBranch(this.path);
this._branch = Container.instance.git.getBranch(this.path);
}
return this._branch;
}
@ -551,7 +555,7 @@ export class Repository implements Disposable {
sort?: boolean | BranchSortOptions;
} = {},
): Promise<GitBranch[]> {
return Container.git.getBranches(this.path, options);
return Container.instance.git.getBranches(this.path, options);
}
getBranchesAndOrTags(
@ -561,19 +565,19 @@ export class Repository implements Disposable {
sort?: boolean | { branches?: BranchSortOptions; tags?: TagSortOptions };
} = {},
) {
return Container.git.getBranchesAndOrTags(this.path, options);
return Container.instance.git.getBranchesAndOrTags(this.path, options);
}
getChangedFilesCount(sha?: string): Promise<GitDiffShortStat | undefined> {
return Container.git.getChangedFilesCount(this.path, sha);
return Container.instance.git.getChangedFilesCount(this.path, sha);
}
getCommit(ref: string): Promise<GitLogCommit | undefined> {
return Container.git.getCommit(this.path, ref);
return Container.instance.git.getCommit(this.path, ref);
}
getContributors(options?: { all?: boolean; ref?: string; stats?: boolean }): Promise<GitContributor[]> {
return Container.git.getContributors(this.path, options);
return Container.instance.git.getContributors(this.path, options);
}
private _lastFetched: number | undefined;
@ -581,7 +585,7 @@ export class Repository implements Disposable {
async getLastFetched(): Promise<number> {
if (this._lastFetched == null) {
const hasRemotes = await this.hasRemotes();
if (!hasRemotes || Container.vsls.isMaybeGuest) return 0;
if (!hasRemotes || Container.instance.vsls.isMaybeGuest) return 0;
}
try {
@ -598,11 +602,11 @@ export class Repository implements Disposable {
}
getMergeStatus(): Promise<GitMergeStatus | undefined> {
return Container.git.getMergeStatus(this.path);
return Container.instance.git.getMergeStatus(this.path);
}
getRebaseStatus(): Promise<GitRebaseStatus | undefined> {
return Container.git.getRebaseStatus(this.path);
return Container.instance.git.getRebaseStatus(this.path);
}
async getRemote(remote: string): Promise<GitRemote | undefined> {
@ -617,7 +621,7 @@ export class Repository implements Disposable {
}
// Since we are caching the results, always sort
this._remotes = Container.git.getRemotesCore(this.path, this._providers, { sort: true });
this._remotes = Container.instance.git.getRemotesCore(this.path, this._providers, { sort: true });
void this.subscribeToRemotes(this._remotes);
}
@ -625,7 +629,9 @@ export class Repository implements Disposable {
}
async getRichRemote(connectedOnly: boolean = false): Promise<GitRemote<RichRemoteProvider> | undefined> {
return Container.git.getRichRemoteProvider(await this.getRemotes(), { includeDisconnected: !connectedOnly });
return Container.instance.git.getRichRemoteProvider(await this.getRemotes(), {
includeDisconnected: !connectedOnly,
});
}
private async subscribeToRemotes(remotes: Promise<GitRemote[]>) {
@ -642,15 +648,15 @@ export class Repository implements Disposable {
}
getStash(): Promise<GitStash | undefined> {
return Container.git.getStash(this.path);
return Container.instance.git.getStash(this.path);
}
getStatus(): Promise<GitStatus | undefined> {
return Container.git.getStatusForRepo(this.path);
return Container.instance.git.getStatusForRepo(this.path);
}
getTags(options?: { filter?: (t: GitTag) => boolean; sort?: boolean | TagSortOptions }): Promise<GitTag[]> {
return Container.git.getTags(this.path, options);
return Container.instance.git.getTags(this.path, options);
}
async hasRemotes(): Promise<boolean> {
@ -698,7 +704,7 @@ export class Repository implements Disposable {
this.path,
));
} else if (configuration.getAny<boolean>(BuiltInGitConfiguration.FetchOnPull, Uri.file(this.path))) {
void (await Container.git.fetch(this.path));
void (await Container.instance.git.fetch(this.path));
}
this.fireChange(RepositoryChange.Unknown);
@ -735,7 +741,7 @@ export class Repository implements Disposable {
}
private async showCreatePullRequestPrompt(remoteName: string, branch: GitBranchReference) {
if (!Container.actionRunners.count('createPullRequest')) return;
if (!Container.instance.actionRunners.count('createPullRequest')) return;
if (!(await Messages.showCreatePullRequestPrompt(branch.name))) return;
const remote = await this.getRemote(remoteName);
@ -871,11 +877,11 @@ export class Repository implements Disposable {
search: SearchPattern,
options: { limit?: number; skip?: number } = {},
): Promise<GitLog | undefined> {
return Container.git.getLogForSearch(this.path, search, options);
return Container.instance.git.getLogForSearch(this.path, search, options);
}
get starred() {
const starred = Container.context.workspaceState.get<Starred>(WorkspaceState.StarredRepositories);
const starred = Container.instance.context.workspaceState.get<Starred>(WorkspaceState.StarredRepositories);
return starred != null && starred[this.id] === true;
}
@ -886,7 +892,7 @@ export class Repository implements Disposable {
@gate(() => '')
@log()
async stashApply(stashName: string, options: { deleteAfter?: boolean } = {}) {
void (await Container.git.stashApply(this.path, stashName, options));
void (await Container.instance.git.stashApply(this.path, stashName, options));
this.fireChange(RepositoryChange.Stash);
}
@ -894,7 +900,7 @@ export class Repository implements Disposable {
@gate(() => '')
@log()
async stashDelete(stashName: string, ref?: string) {
void (await Container.git.stashDelete(this.path, stashName, ref));
void (await Container.instance.git.stashDelete(this.path, stashName, ref));
this.fireChange(RepositoryChange.Stash);
}
@ -902,7 +908,7 @@ export class Repository implements Disposable {
@gate(() => '')
@log()
async stashSave(message?: string, uris?: Uri[], options: { includeUntracked?: boolean; keepIndex?: boolean } = {}) {
void (await Container.git.stashSave(this.path, message, uris, options));
void (await Container.instance.git.stashSave(this.path, message, uris, options));
this.fireChange(RepositoryChange.Stash);
}
@ -925,7 +931,7 @@ export class Repository implements Disposable {
private async switchCore(ref: string, options: { createBranch?: string } = {}) {
try {
void (await Container.git.checkout(this.path, ref, options));
void (await Container.instance.git.checkout(this.path, ref, options));
this.fireChange(RepositoryChange.Unknown);
} catch (ex) {
@ -954,7 +960,7 @@ export class Repository implements Disposable {
}
private async updateStarredCore(key: WorkspaceState, id: string, star: boolean) {
let starred = Container.context.workspaceState.get<Starred>(key);
let starred = Container.instance.context.workspaceState.get<Starred>(key);
if (starred === undefined) {
starred = Object.create(null) as Starred;
}
@ -965,7 +971,7 @@ export class Repository implements Disposable {
const { [id]: _, ...rest } = starred;
starred = rest;
}
await Container.context.workspaceState.update(key, starred);
await Container.instance.context.workspaceState.update(key, starred);
this.fireChange(RepositoryChange.Starred);
}
@ -1081,7 +1087,7 @@ export class Repository implements Disposable {
this._pendingFileSystemChange = undefined;
const uris = await Container.git.excludeIgnoredUris(this.path, e.uris);
const uris = await Container.instance.git.excludeIgnoredUris(this.path, e.uris);
if (uris.length === 0) return;
if (uris.length !== e.uris.length) {

+ 1
- 1
src/git/models/stashCommit.ts View File

@ -58,7 +58,7 @@ export class GitStashCommit extends GitLogCommit {
// Check for any untracked files -- since git doesn't return them via `git stash list` :(
// See https://stackoverflow.com/questions/12681529/
const commit = await Container.git.getCommit(this.repoPath, `${this.stashName}^3`);
const commit = await Container.instance.git.getCommit(this.repoPath, `${this.stashName}^3`);
if (commit != null && commit.files.length !== 0) {
// Since these files are untracked -- make them look that way
const files = commit.files.map(s => ({

+ 1
- 1
src/git/models/status.ts View File

@ -234,7 +234,7 @@ export class GitStatus {
async getRemote(): Promise<GitRemote | undefined> {
if (this.upstream == null) return undefined;
const remotes = await Container.git.getRemotes(this.repoPath);
const remotes = await Container.instance.git.getRemotes(this.repoPath);
if (remotes.length === 0) return undefined;
const remoteName = GitBranch.getRemote(this.upstream);

+ 6
- 6
src/git/remotes/github.ts View File

@ -188,7 +188,7 @@ export class GitHubRemote extends RichRemoteProvider {
},
): Promise<Account | undefined> {
const [owner, repo] = this.splitPath();
return (await Container.github)?.getAccountForCommit(this, accessToken, owner, repo, ref, {
return (await Container.instance.github)?.getAccountForCommit(this, accessToken, owner, repo, ref, {
...options,
baseUrl: this.apiBaseUrl,
});
@ -202,7 +202,7 @@ export class GitHubRemote extends RichRemoteProvider {
},
): Promise<Account | undefined> {
const [owner, repo] = this.splitPath();
return (await Container.github)?.getAccountForEmail(this, accessToken, owner, repo, email, {
return (await Container.instance.github)?.getAccountForEmail(this, accessToken, owner, repo, email, {
...options,
baseUrl: this.apiBaseUrl,
});
@ -212,7 +212,7 @@ export class GitHubRemote extends RichRemoteProvider {
accessToken,
}: AuthenticationSession): Promise<DefaultBranch | undefined> {
const [owner, repo] = this.splitPath();
return (await Container.github)?.getDefaultBranch(this, accessToken, owner, repo, {
return (await Container.instance.github)?.getDefaultBranch(this, accessToken, owner, repo, {
baseUrl: this.apiBaseUrl,
});
}
@ -221,7 +221,7 @@ export class GitHubRemote extends RichRemoteProvider {
id: string,
): Promise<IssueOrPullRequest | undefined> {
const [owner, repo] = this.splitPath();
return (await Container.github)?.getIssueOrPullRequest(this, accessToken, owner, repo, Number(id), {
return (await Container.instance.github)?.getIssueOrPullRequest(this, accessToken, owner, repo, Number(id), {
baseUrl: this.apiBaseUrl,
});
}
@ -237,7 +237,7 @@ export class GitHubRemote extends RichRemoteProvider {
const [owner, repo] = this.splitPath();
const { include, ...opts } = options ?? {};
return (await Container.github)?.getPullRequestForBranch(this, accessToken, owner, repo, branch, {
return (await Container.instance.github)?.getPullRequestForBranch(this, accessToken, owner, repo, branch, {
...opts,
include: include?.map(s => GitHubPullRequest.toState(s)),
baseUrl: this.apiBaseUrl,
@ -249,7 +249,7 @@ export class GitHubRemote extends RichRemoteProvider {
ref: string,
): Promise<PullRequest | undefined> {
const [owner, repo] = this.splitPath();
return (await Container.github)?.getPullRequestForCommit(this, accessToken, owner, repo, ref, {
return (await Container.instance.github)?.getPullRequestForCommit(this, accessToken, owner, repo, ref, {
baseUrl: this.apiBaseUrl,
});
}

+ 8
- 8
src/git/remotes/provider.ts View File

@ -281,7 +281,7 @@ export abstract class RichRemoteProvider extends RemoteProvider {
constructor(domain: string, path: string, protocol?: string, name?: string, custom?: boolean) {
super(domain, path, protocol, name, custom);
Container.context.subscriptions.push(
Container.instance.context.subscriptions.push(
// TODO@eamodio revisit how connections are linked or not
Authentication.onDidChange(e => {
if (e.key !== this.key) return;
@ -346,7 +346,7 @@ export abstract class RichRemoteProvider extends RemoteProvider {
this._session = null;
if (disconnected) {
void Container.context.workspaceState.update(this.connectedKey, false);
void Container.instance.context.workspaceState.update(this.connectedKey, false);
this._onDidChange.fire();
if (!silent) {
@ -570,11 +570,11 @@ export abstract class RichRemoteProvider extends RemoteProvider {
private async ensureSession(createIfNeeded: boolean): Promise<AuthenticationSession | undefined> {
if (this._session != null) return this._session;
if (!Container.config.integrations.enabled) return undefined;
if (!Container.instance.config.integrations.enabled) return undefined;
if (createIfNeeded) {
await Container.context.workspaceState.update(this.connectedKey, undefined);
} else if (Container.context.workspaceState.get<boolean>(this.connectedKey) === false) {
await Container.instance.context.workspaceState.update(this.connectedKey, undefined);
} else if (Container.instance.context.workspaceState.get<boolean>(this.connectedKey) === false) {
return undefined;
}
@ -584,7 +584,7 @@ export abstract class RichRemoteProvider extends RemoteProvider {
createIfNone: createIfNeeded,
});
} catch (ex) {
await Container.context.workspaceState.update(this.connectedKey, undefined);
await Container.instance.context.workspaceState.update(this.connectedKey, undefined);
if (ex instanceof Error && ex.message.includes('User did not consent')) {
return undefined;
@ -594,14 +594,14 @@ export abstract class RichRemoteProvider extends RemoteProvider {
}
if (session === undefined && !createIfNeeded) {
await Container.context.workspaceState.update(this.connectedKey, undefined);
await Container.instance.context.workspaceState.update(this.connectedKey, undefined);
}
this._session = session ?? null;
this.invalidClientExceptionCount = 0;
if (session != null) {
await Container.context.workspaceState.update(this.connectedKey, true);
await Container.instance.context.workspaceState.update(this.connectedKey, true);
this._onDidChange.fire();
_onDidChangeAuthentication.fire({ reason: 'connected', key: this.key });

+ 12
- 12
src/hovers/hovers.ts View File

@ -50,11 +50,11 @@ export namespace Hovers {
editorLine = commitLine.line - 1;
// TODO: Doesn't work with dirty files -- pass in editor? or contents?
hunkLine = await Container.git.getDiffForLine(uri, editorLine, ref, documentRef, originalFileName);
hunkLine = await Container.instance.git.getDiffForLine(uri, editorLine, ref, documentRef, originalFileName);
// If we didn't find a diff & ref is undefined (meaning uncommitted), check for a staged diff
if (hunkLine == null && ref == null) {
hunkLine = await Container.git.getDiffForLine(
hunkLine = await Container.instance.git.getDiffForLine(
uri,
editorLine,
undefined,
@ -200,7 +200,7 @@ export namespace Hovers {
dateFormat = 'MMMM Do, YYYY h:mma';
}
const remotes = await Container.git.getRemotes(commit.repoPath, { sort: true });
const remotes = await Container.instance.git.getRemotes(commit.repoPath, { sort: true });
const [previousLineDiffUris, autolinkedIssuesOrPullRequests, pr, presence] = await Promise.all([
commit.isUncommitted ? commit.getPreviousLineDiffUris(uri, editorLine, uri.sha) : undefined,
@ -218,7 +218,7 @@ export namespace Hovers {
'pullRequestState',
),
}),
Container.vsls.maybeGetPresence(commit.email),
Container.instance.vsls.maybeGetPresence(commit.email),
]);
const details = await CommitFormatter.fromTemplateAsync(format, commit, {
@ -247,7 +247,7 @@ export namespace Hovers {
}
function getDiffFromHunkLine(hunkLine: GitDiffHunkLine, diffStyle?: 'line' | 'hunk'): string {
if (diffStyle === 'hunk' || (diffStyle == null && Container.config.hovers.changesDiff === 'hunk')) {
if (diffStyle === 'hunk' || (diffStyle == null && Container.instance.config.hovers.changesDiff === 'hunk')) {
return getDiffFromHunk(hunkLine.hunk);
}
@ -263,16 +263,16 @@ export namespace Hovers {
const start = process.hrtime();
if (
!Container.config.hovers.autolinks.enabled ||
!Container.config.hovers.autolinks.enhanced ||
!CommitFormatter.has(Container.config.hovers.detailsMarkdownFormat, 'message')
!Container.instance.config.hovers.autolinks.enabled ||
!Container.instance.config.hovers.autolinks.enhanced ||
!CommitFormatter.has(Container.instance.config.hovers.detailsMarkdownFormat, 'message')
) {
Logger.debug(cc, `completed ${GlyphChars.Dot} ${Strings.getDurationMilliseconds(start)} ms`);
return undefined;
}
const remote = await Container.git.getRichRemoteProvider(remotes);
const remote = await Container.instance.git.getRichRemoteProvider(remotes);
if (remote?.provider == null) {
Logger.debug(cc, `completed ${GlyphChars.Dot} ${Strings.getDurationMilliseconds(start)} ms`);
@ -283,7 +283,7 @@ export namespace Hovers {
const timeout = 250;
try {
const autolinks = await Container.autolinks.getIssueOrPullRequestLinks(message, remote, {
const autolinks = await Container.instance.autolinks.getIssueOrPullRequestLinks(message, remote, {
timeout: timeout,
});
@ -347,7 +347,7 @@ export namespace Hovers {
return undefined;
}
const remote = await Container.git.getRichRemoteProvider(remotes, { includeDisconnected: true });
const remote = await Container.instance.git.getRichRemoteProvider(remotes, { includeDisconnected: true });
if (remote?.provider == null) {
Logger.debug(cc, `completed ${GlyphChars.Dot} ${Strings.getDurationMilliseconds(start)} ms`);
@ -363,7 +363,7 @@ export namespace Hovers {
}
try {
const pr = await Container.git.getPullRequestForCommit(ref, provider, { timeout: 250 });
const pr = await Container.instance.git.getPullRequestForCommit(ref, provider, { timeout: 250 });
Logger.debug(cc, `completed ${GlyphChars.Dot} ${Strings.getDurationMilliseconds(start)} ms`);

+ 34
- 28
src/hovers/lineHoverController.ts View File

@ -24,32 +24,38 @@ export class LineHoverController implements Disposable {
private _hoverProviderDisposable: Disposable | undefined;
private _uri: Uri | undefined;
constructor() {
this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this));
this.onConfigurationChanged();
constructor(private readonly container: Container) {
this._disposable = Disposable.from(
container.onReady(this.onReady, this),
configuration.onDidChange(this.onConfigurationChanged, this),
);
}
dispose() {
this.unregister();
Container.lineTracker.stop(this);
this.container.lineTracker.stop(this);
this._disposable.dispose();
}
private onReady(): void {
this.onConfigurationChanged();
}
private onConfigurationChanged(e?: ConfigurationChangeEvent) {
if (!configuration.changed(e, 'hovers.enabled') && !configuration.changed(e, 'hovers.currentLine.enabled')) {
return;
}
if (Container.config.hovers.enabled && Container.config.hovers.currentLine.enabled) {
Container.lineTracker.start(
if (this.container.config.hovers.enabled && this.container.config.hovers.currentLine.enabled) {
this.container.lineTracker.start(
this,
Container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this),
this.container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this),
);
this.register(window.activeTextEditor);
} else {
Container.lineTracker.stop(this);
this.container.lineTracker.stop(this);
this.unregister();
}
}
@ -88,21 +94,21 @@ export class LineHoverController implements Disposable {
position: Position,
_token: CancellationToken,
): Promise<Hover | undefined> {
if (!Container.lineTracker.includes(position.line)) return undefined;
if (!this.container.lineTracker.includes(position.line)) return undefined;
const lineState = Container.lineTracker.getState(position.line);
const lineState = this.container.lineTracker.getState(position.line);
const commit = lineState?.commit;
if (commit == null) return undefined;
// Avoid double annotations if we are showing the whole-file hover blame annotations
if (Container.config.hovers.annotations.details) {
const fileAnnotations = await Container.fileAnnotations.getAnnotationType(window.activeTextEditor);
if (this.container.config.hovers.annotations.details) {
const fileAnnotations = await this.container.fileAnnotations.getAnnotationType(window.activeTextEditor);
if (fileAnnotations === FileAnnotationType.Blame) return undefined;
}
const wholeLine = Container.config.hovers.currentLine.over === 'line';
const wholeLine = this.container.config.hovers.currentLine.over === 'line';
// If we aren't showing the hover over the whole line, make sure the annotation is on
if (!wholeLine && Container.lineAnnotations.suspended) return undefined;
if (!wholeLine && this.container.lineAnnotations.suspended) return undefined;
const range = document.validateRange(
new Range(position.line, wholeLine ? 0 : Number.MAX_SAFE_INTEGER, position.line, Number.MAX_SAFE_INTEGER),
@ -112,7 +118,7 @@ export class LineHoverController implements Disposable {
// Get the full commit message -- since blame only returns the summary
let logCommit = lineState?.logCommit;
if (logCommit == null && !commit.isUncommitted) {
logCommit = await Container.git.getCommitForFile(commit.repoPath, commit.uri.fsPath, {
logCommit = await this.container.git.getCommitForFile(commit.repoPath, commit.uri.fsPath, {
ref: commit.sha,
});
if (logCommit != null) {
@ -131,19 +137,19 @@ export class LineHoverController implements Disposable {
const commitLine = commit.lines.find(l => l.line === line) ?? commit.lines[0];
editorLine = commitLine.originalLine - 1;
const trackedDocument = await Container.tracker.get(document);
const trackedDocument = await this.container.tracker.get(document);
if (trackedDocument == null) return undefined;
const message = await Hovers.detailsMessage(
logCommit ?? commit,
trackedDocument.uri,
editorLine,
Container.config.hovers.detailsMarkdownFormat,
Container.config.defaultDateFormat,
this.container.config.hovers.detailsMarkdownFormat,
this.container.config.defaultDateFormat,
{
autolinks: Container.config.hovers.autolinks.enabled,
autolinks: this.container.config.hovers.autolinks.enabled,
pullRequests: {
enabled: Container.config.hovers.pullRequests.enabled,
enabled: this.container.config.hovers.pullRequests.enabled,
},
},
);
@ -162,28 +168,28 @@ export class LineHoverController implements Disposable {
position: Position,
_token: CancellationToken,
): Promise<Hover | undefined> {
if (!Container.lineTracker.includes(position.line)) return undefined;
if (!this.container.lineTracker.includes(position.line)) return undefined;
const lineState = Container.lineTracker.getState(position.line);
const lineState = this.container.lineTracker.getState(position.line);
const commit = lineState?.commit;
if (commit == null) return undefined;
// Avoid double annotations if we are showing the whole-file hover blame annotations
if (Container.config.hovers.annotations.changes) {
const fileAnnotations = await Container.fileAnnotations.getAnnotationType(window.activeTextEditor);
if (this.container.config.hovers.annotations.changes) {
const fileAnnotations = await this.container.fileAnnotations.getAnnotationType(window.activeTextEditor);
if (fileAnnotations === FileAnnotationType.Blame) return undefined;
}
const wholeLine = Container.config.hovers.currentLine.over === 'line';
const wholeLine = this.container.config.hovers.currentLine.over === 'line';
// If we aren't showing the hover over the whole line, make sure the annotation is on
if (!wholeLine && Container.lineAnnotations.suspended) return undefined;
if (!wholeLine && this.container.lineAnnotations.suspended) return undefined;
const range = document.validateRange(
new Range(position.line, wholeLine ? 0 : Number.MAX_SAFE_INTEGER, position.line, Number.MAX_SAFE_INTEGER),
);
if (!wholeLine && range.start.character !== position.character) return undefined;
const trackedDocument = await Container.tracker.get(document);
const trackedDocument = await this.container.tracker.get(document);
if (trackedDocument == null) return undefined;
const message = await Hovers.changesMessage(commit, trackedDocument.uri, position.line);
@ -201,7 +207,7 @@ export class LineHoverController implements Disposable {
if (editor == null) return;
const cfg = Container.config.hovers;
const cfg = this.container.config.hovers;
if (!cfg.enabled || !cfg.currentLine.enabled || (!cfg.currentLine.details && !cfg.currentLine.changes)) return;
this._uri = editor.document.uri;

+ 27
- 23
src/partners.ts View File

@ -48,33 +48,37 @@ export function registerPartnerActionRunners(context: ExtensionContext): void {
function registerLiveShare(context: ExtensionContext) {
context.subscriptions.push(
Container.actionRunners.registerBuiltInPartner<HoverCommandsActionContext>('liveshare', 'hover.commands', {
name: 'Live Share',
label: (context: ActionContext) => {
if (context.type === 'hover.commands') {
if (context.commit.author.name !== 'You') {
return `$(live-share) Invite ${context.commit.author.name}${
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
context.commit.author.presence?.statusText
? ` (${context.commit.author.presence?.statusText})`
: ''
} to a Live Share Session`;
Container.instance.actionRunners.registerBuiltInPartner<HoverCommandsActionContext>(
'liveshare',
'hover.commands',
{
name: 'Live Share',
label: (context: ActionContext) => {
if (context.type === 'hover.commands') {
if (context.commit.author.name !== 'You') {
return `$(live-share) Invite ${context.commit.author.name}${
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
context.commit.author.presence?.statusText
? ` (${context.commit.author.presence?.statusText})`
: ''
} to a Live Share Session`;
}
}
}
return '$(live-share) Start a Live Share Session';
},
run: async (context: ActionContext) => {
if (context.type !== 'hover.commands' || context.commit.author.name === 'You') {
await executeCommand<InviteToLiveShareCommandArgs>(Commands.InviteToLiveShare, {});
return '$(live-share) Start a Live Share Session';
},
run: async (context: ActionContext) => {
if (context.type !== 'hover.commands' || context.commit.author.name === 'You') {
await executeCommand<InviteToLiveShareCommandArgs>(Commands.InviteToLiveShare, {});
return;
}
return;
}
await executeCommand<InviteToLiveShareCommandArgs>(Commands.InviteToLiveShare, {
email: context.commit.author.email,
});
await executeCommand<InviteToLiveShareCommandArgs>(Commands.InviteToLiveShare, {
email: context.commit.author.email,
});
},
},
}),
),
);
}

+ 1
- 1
src/quickpicks/commitPicker.ts View File

@ -100,7 +100,7 @@ export namespace CommitPicker {
let scope: KeyboardScope | undefined;
if (options?.keys != null && options.keys.length !== 0 && options?.onDidPressKey !== null) {
scope = Container.keyboard.createScope(
scope = Container.instance.keyboard.createScope(
Object.fromEntries(
options.keys.map(key => [
key,

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save