Browse Source

Splits out new `getFirstCommitSha`

Aligns with eventual cloud patch changes
main
Eric Amodio 1 year ago
parent
commit
3bce79a8d8
7 changed files with 87 additions and 86 deletions
  1. +6
    -6
      src/env/node/git/localGitProvider.ts
  2. +1
    -1
      src/git/gitProvider.ts
  3. +10
    -6
      src/git/gitProviderService.ts
  4. +0
    -5
      src/plus/github/githubGitProvider.ts
  5. +3
    -3
      src/telemetry/usageTracker.ts
  6. +55
    -51
      src/uris/deepLinks/deepLink.ts
  7. +12
    -14
      src/uris/deepLinks/deepLinkService.ts

+ 6
- 6
src/env/node/git/localGitProvider.ts View File

@ -2917,6 +2917,12 @@ export class LocalGitProvider implements GitProvider, Disposable {
return files[0]; return files[0];
} }
@log()
async getFirstCommitSha(repoPath: string): Promise<string | undefined> {
const data = await this.git.rev_list(repoPath, 'HEAD', { maxParents: 0 });
return data?.[0];
}
@gate() @gate()
@debug() @debug()
async getGitDir(repoPath: string): Promise<GitDir> { async getGitDir(repoPath: string): Promise<GitDir> {
@ -4442,12 +4448,6 @@ export class LocalGitProvider implements GitProvider, Disposable {
return GitTreeParser.parse(data) ?? []; return GitTreeParser.parse(data) ?? [];
} }
@log()
async getUniqueRepositoryId(repoPath: string): Promise<string | undefined> {
const data = await this.git.rev_list(repoPath, 'HEAD', { maxParents: 0 });
return data?.[0];
}
@log({ args: { 1: false } }) @log({ args: { 1: false } })
async hasBranchOrTag( async hasBranchOrTag(
repoPath: string | undefined, repoPath: string | undefined,

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

@ -308,6 +308,7 @@ export interface GitProvider extends Disposable {
options?: { filters?: GitDiffFilter[] | undefined; similarityThreshold?: number | undefined }, options?: { filters?: GitDiffFilter[] | undefined; similarityThreshold?: number | undefined },
): Promise<GitFile[] | undefined>; ): Promise<GitFile[] | undefined>;
getFileStatusForCommit(repoPath: string, uri: Uri, ref: string): Promise<GitFile | undefined>; getFileStatusForCommit(repoPath: string, uri: Uri, ref: string): Promise<GitFile | undefined>;
getFirstCommitSha?(repoPath: string): Promise<string | undefined>;
getGitDir?(repoPath: string): Promise<GitDir | undefined>; getGitDir?(repoPath: string): Promise<GitDir | undefined>;
getLastFetchedTimestamp(repoPath: string): Promise<number | undefined>; getLastFetchedTimestamp(repoPath: string): Promise<number | undefined>;
getLog( getLog(
@ -406,7 +407,6 @@ export interface GitProvider extends Disposable {
): Promise<PagedResult<GitTag>>; ): Promise<PagedResult<GitTag>>;
getTreeEntryForRevision(repoPath: string, path: string, ref: string): Promise<GitTreeEntry | undefined>; getTreeEntryForRevision(repoPath: string, path: string, ref: string): Promise<GitTreeEntry | undefined>;
getTreeForRevision(repoPath: string, ref: string): Promise<GitTreeEntry[]>; getTreeForRevision(repoPath: string, ref: string): Promise<GitTreeEntry[]>;
getUniqueRepositoryId(repoPath: string): Promise<string | undefined>;
hasBranchOrTag( hasBranchOrTag(
repoPath: string | undefined, repoPath: string | undefined,
options?: { options?: {

+ 10
- 6
src/git/gitProviderService.ts View File

@ -97,8 +97,6 @@ const weightedDefaultBranches = new Map([
['development', 1], ['development', 1],
]); ]);
const missingRepositoryId = '-';
export type GitProvidersChangeEvent = { export type GitProvidersChangeEvent = {
readonly added: readonly GitProvider[]; readonly added: readonly GitProvider[];
readonly removed: readonly GitProvider[]; readonly removed: readonly GitProvider[];
@ -2438,12 +2436,18 @@ export class GitProviderService implements Disposable {
} }
@log() @log()
async getUniqueRepositoryId(repoPath: string | Uri): Promise<string> {
async getFirstCommitSha(repoPath: string | Uri): Promise<string | undefined> {
const { provider, path } = this.getProvider(repoPath); const { provider, path } = this.getProvider(repoPath);
const id = await provider.getUniqueRepositoryId(path);
if (id != null) return id;
try {
return await provider.getFirstCommitSha?.(path);
} catch {
return undefined;
}
}
return missingRepositoryId;
@log()
getUniqueRepositoryId(repoPath: string | Uri): Promise<string | undefined> {
return this.getFirstCommitSha(repoPath);
} }
@log({ args: { 1: false } }) @log({ args: { 1: false } })

+ 0
- 5
src/plus/github/githubGitProvider.ts View File

@ -2771,11 +2771,6 @@ export class GitHubGitProvider implements GitProvider, Disposable {
return []; return [];
} }
async getUniqueRepositoryId(_repoPath: string): Promise<string | undefined> {
// TODO@ramint implement this if there is a way.
return undefined;
}
@log() @log()
async hasBranchOrTag( async hasBranchOrTag(
repoPath: string | undefined, repoPath: string | undefined,

+ 3
- 3
src/telemetry/usageTracker.ts View File

@ -11,11 +11,13 @@ export interface TrackedUsage {
} }
export type TrackedUsageFeatures = export type TrackedUsageFeatures =
| 'accountView'
| 'branchesView' | 'branchesView'
| 'commitDetailsView' | 'commitDetailsView'
| 'commitsView' | 'commitsView'
| 'contributorsView' | 'contributorsView'
| 'fileHistoryView' | 'fileHistoryView'
| 'focusWebview'
| 'graphDetailsView' | 'graphDetailsView'
| 'graphView' | 'graphView'
| 'graphWebview' | 'graphWebview'
@ -31,9 +33,7 @@ export type TrackedUsageFeatures =
| 'timelineWebview' | 'timelineWebview'
| 'timelineView' | 'timelineView'
| 'welcomeWebview' | 'welcomeWebview'
| 'workspaceView'
| 'focusWebview'
| 'accountView';
| 'workspaceView';
export type TrackedUsageKeys = `${TrackedUsageFeatures}:shown`; export type TrackedUsageKeys = `${TrackedUsageFeatures}:shown`;
export type UsageChangeEvent = { export type UsageChangeEvent = {

+ 55
- 51
src/uris/deepLinks/deepLink.ts View File

@ -62,65 +62,69 @@ export function parseDeepLinkUri(uri: Uri): DeepLink | undefined {
// For example, if the uri is /link/r/{repoId}/b/{branchName}?url={remoteUrl}, // For example, if the uri is /link/r/{repoId}/b/{branchName}?url={remoteUrl},
// the link target id is {branchName} // the link target id is {branchName}
const [, type, prefix, mainId, target, ...rest] = uri.path.split('/'); const [, type, prefix, mainId, target, ...rest] = uri.path.split('/');
if (type !== 'link' || (prefix !== DeepLinkType.Repository && prefix !== DeepLinkType.Workspace)) {
return undefined;
}
if (type !== 'link') return undefined;
const urlParams = new URLSearchParams(uri.query); const urlParams = new URLSearchParams(uri.query);
let remoteUrl = urlParams.get('url') ?? undefined;
if (remoteUrl != null) {
remoteUrl = decodeURIComponent(remoteUrl);
}
let repoPath = urlParams.get('path') ?? undefined;
if (repoPath != null) {
repoPath = decodeURIComponent(repoPath);
}
if (!remoteUrl && !repoPath && prefix !== DeepLinkType.Workspace) return undefined;
if (prefix === DeepLinkType.Workspace) {
return {
type: DeepLinkType.Workspace,
mainId: mainId,
};
}
switch (prefix) {
case DeepLinkType.Repository: {
let remoteUrl = urlParams.get('url') ?? undefined;
if (remoteUrl != null) {
remoteUrl = decodeURIComponent(remoteUrl);
}
let repoPath = urlParams.get('path') ?? undefined;
if (repoPath != null) {
repoPath = decodeURIComponent(repoPath);
}
if (!remoteUrl && !repoPath) return undefined;
if (target == null) {
return {
type: DeepLinkType.Repository,
mainId: mainId,
remoteUrl: remoteUrl,
repoPath: repoPath,
};
}
if (target == null) {
return {
type: DeepLinkType.Repository,
mainId: mainId,
remoteUrl: remoteUrl,
repoPath: repoPath,
};
}
if (rest == null || rest.length === 0) return undefined;
if (rest == null || rest.length === 0) return undefined;
let targetId: string;
let secondaryTargetId: string | undefined;
let secondaryRemoteUrl: string | undefined;
const joined = rest.join('/');
let targetId: string;
let secondaryTargetId: string | undefined;
let secondaryRemoteUrl: string | undefined;
const joined = rest.join('/');
if (target === DeepLinkType.Comparison) {
const split = joined.split(/(\.\.\.|\.\.)/);
if (split.length !== 3) return undefined;
targetId = split[0];
secondaryTargetId = split[2];
secondaryRemoteUrl = urlParams.get('prRepoUrl') ?? undefined;
if (secondaryRemoteUrl != null) {
secondaryRemoteUrl = decodeURIComponent(secondaryRemoteUrl);
if (target === DeepLinkType.Comparison) {
const split = joined.split(/(\.\.\.|\.\.)/);
if (split.length !== 3) return undefined;
targetId = split[0];
secondaryTargetId = split[2];
secondaryRemoteUrl = urlParams.get('prRepoUrl') ?? undefined;
if (secondaryRemoteUrl != null) {
secondaryRemoteUrl = decodeURIComponent(secondaryRemoteUrl);
}
} else {
targetId = joined;
}
return {
type: target as DeepLinkType,
mainId: mainId,
remoteUrl: remoteUrl,
repoPath: repoPath,
targetId: targetId,
secondaryTargetId: secondaryTargetId,
secondaryRemoteUrl: secondaryRemoteUrl,
};
} }
} else {
targetId = joined;
}
case DeepLinkType.Workspace:
return {
type: DeepLinkType.Workspace,
mainId: mainId,
};
return {
type: target as DeepLinkType,
mainId: mainId,
remoteUrl: remoteUrl,
repoPath: repoPath,
targetId: targetId,
secondaryTargetId: secondaryTargetId,
secondaryRemoteUrl: secondaryRemoteUrl,
};
default:
return undefined;
}
} }
export const enum DeepLinkServiceState { export const enum DeepLinkServiceState {

+ 12
- 14
src/uris/deepLinks/deepLinkService.ts View File

@ -25,18 +25,18 @@ import {
parseDeepLinkUri, parseDeepLinkUri,
} from './deepLink'; } from './deepLink';
const missingRepositoryId = '-';
export class DeepLinkService implements Disposable { export class DeepLinkService implements Disposable {
private readonly _disposables: Disposable[] = []; private readonly _disposables: Disposable[] = [];
private _context: DeepLinkServiceContext; private _context: DeepLinkServiceContext;
private readonly _onDeepLinkProgressUpdated: EventEmitter<DeepLinkProgress>;
private readonly _onDeepLinkProgressUpdated = new EventEmitter<DeepLinkProgress>();
constructor(private readonly container: Container) { constructor(private readonly container: Container) {
this._context = { this._context = {
state: DeepLinkServiceState.Idle, state: DeepLinkServiceState.Idle,
}; };
this._onDeepLinkProgressUpdated = new EventEmitter<DeepLinkProgress>();
this._disposables.push( this._disposables.push(
container.uri.onDidReceiveUri(async (uri: Uri) => { container.uri.onDidReceiveUri(async (uri: Uri) => {
const link = parseDeepLinkUri(uri); const link = parseDeepLinkUri(uri);
@ -426,10 +426,13 @@ export class DeepLinkService implements Disposable {
return; return;
} }
case DeepLinkServiceState.TypeMatch: { case DeepLinkServiceState.TypeMatch: {
if (targetType === DeepLinkType.Workspace) {
action = DeepLinkServiceAction.LinkIsWorkspaceType;
} else {
action = DeepLinkServiceAction.LinkIsRepoType;
switch (targetType) {
case DeepLinkType.Workspace:
action = DeepLinkServiceAction.LinkIsWorkspaceType;
break;
default:
action = DeepLinkServiceAction.LinkIsRepoType;
break;
} }
break; break;
@ -471,7 +474,7 @@ export class DeepLinkService implements Disposable {
} }
} }
if (mainId != null && mainId !== '-') {
if (mainId != null && mainId !== missingRepositoryId) {
// Repo ID can be any valid SHA in the repo, though standard practice is to use the // Repo ID can be any valid SHA in the repo, though standard practice is to use the
// first commit SHA. // first commit SHA.
if (await this.container.git.validateReference(repo.path, mainId)) { if (await this.container.git.validateReference(repo.path, mainId)) {
@ -945,7 +948,6 @@ export class DeepLinkService implements Disposable {
compareRef?: StoredNamedRef, compareRef?: StoredNamedRef,
compareWithRef?: StoredNamedRef, compareWithRef?: StoredNamedRef,
): Promise<URL> { ): Promise<URL> {
let repoId: string | undefined;
let targetType: DeepLinkType | undefined; let targetType: DeepLinkType | undefined;
let targetId: string | undefined; let targetId: string | undefined;
let compareWithTargetId: string | undefined; let compareWithTargetId: string | undefined;
@ -963,11 +965,7 @@ export class DeepLinkService implements Disposable {
} }
const repoPath = typeof refOrIdOrRepoPath !== 'string' ? refOrIdOrRepoPath.repoPath : refOrIdOrRepoPath; const repoPath = typeof refOrIdOrRepoPath !== 'string' ? refOrIdOrRepoPath.repoPath : refOrIdOrRepoPath;
try {
repoId = await this.container.git.getUniqueRepositoryId(repoPath);
} catch {
repoId = '-';
}
const repoId = (await this.container.git.getUniqueRepositoryId(repoPath)) ?? missingRepositoryId;
if (typeof refOrIdOrRepoPath !== 'string') { if (typeof refOrIdOrRepoPath !== 'string') {
switch (refOrIdOrRepoPath.refType) { switch (refOrIdOrRepoPath.refType) {

Loading…
Cancel
Save