Path: blob/main/src/vs/workbench/contrib/git/browser/gitService.ts
13401 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { CancellationToken } from '../../../../base/common/cancellation.js';6import { BugIndicatingError } from '../../../../base/common/errors.js';7import { Disposable, IDisposable, toDisposable } from '../../../../base/common/lifecycle.js';8import { URI } from '../../../../base/common/uri.js';9import { IGitService, IGitExtensionDelegate, GitRef, GitRefQuery, IGitRepository, GitRepositoryState, GitDiffChange } from '../common/gitService.js';10import { ISettableObservable, observableValueOpts } from '../../../../base/common/observable.js';11import { structuralEquals } from '../../../../base/common/equals.js';12import { AutoOpenBarrier } from '../../../../base/common/async.js';13import { ILogService } from '../../../../platform/log/common/log.js';1415export class GitService extends Disposable implements IGitService {16declare readonly _serviceBrand: undefined;1718private _delegate: IGitExtensionDelegate | undefined;19private _delegateBarrier = new AutoOpenBarrier(10_000);2021get repositories(): Iterable<IGitRepository> {22return this._delegate?.repositories ?? [];23}2425constructor(@ILogService private readonly logService: ILogService) {26super();27}2829setDelegate(delegate: IGitExtensionDelegate): IDisposable {30// The delegate can only be set once, since the vscode.git31// extension can only run in one extension host process per32// window.33if (this._delegate) {34this.logService.error('[GitService][setDelegate] GitExtension delegate is already set.');35throw new BugIndicatingError('GitExtension delegate is already set.');36}3738this._delegate = delegate;39this._delegateBarrier.open();4041return toDisposable(() => {42this._delegate = undefined;43});44}4546async openRepository(uri: URI): Promise<IGitRepository | undefined> {47// We need to wait for the delegate to be set before we can open a repository.48// At the moment we are waiting for 10 seconds before we automatically open the49// barrier.50await this._delegateBarrier.wait();5152if (!this._delegate) {53this.logService.warn('[GitService][openRepository] GitExtension delegate is not set after 10 seconds. Cannot open repository.');54return undefined;55}5657return this._delegate.openRepository(uri);58}59}6061export class GitRepository extends Disposable implements IGitRepository {62readonly rootUri: URI;6364readonly state: ISettableObservable<GitRepositoryState>;65updateState(state: GitRepositoryState): void {66this.state.set(state, undefined);67}6869constructor(70rootUri: URI,71initialState: GitRepositoryState,72private readonly delegate: IGitExtensionDelegate73) {74super();7576this.rootUri = rootUri;77this.state = observableValueOpts({ owner: this, equalsFn: structuralEquals }, initialState);78}7980async getRefs(query: GitRefQuery, token?: CancellationToken): Promise<GitRef[]> {81return this.delegate.getRefs(this.rootUri, query, token);82}8384async diffBetweenWithStats(ref1: string, ref2: string, path?: string): Promise<GitDiffChange[]> {85return this.delegate.diffBetweenWithStats(this.rootUri, ref1, ref2, path);86}8788async diffBetweenWithStats2(ref: string, path?: string): Promise<GitDiffChange[]> {89return this.delegate.diffBetweenWithStats2(this.rootUri, ref, path);90}91}929394