From 7077ccd411896b11611121c239746c6c0133635d Mon Sep 17 00:00:00 2001 From: Eric Amodio <eamodio@gmail.com> Date: Tue, 21 Nov 2023 13:03:47 -0500 Subject: [PATCH] Renames --- src/env/node/git/localGitProvider.ts | 89 +++++++++++----------- src/git/gitProvider.ts | 10 +-- src/git/gitProviderService.ts | 67 +++------------- .../webviews/patchDetails/patchDetailsWebview.ts | 2 +- 4 files changed, 62 insertions(+), 106 deletions(-) diff --git a/src/env/node/git/localGitProvider.ts b/src/env/node/git/localGitProvider.ts index 48cba85..c5ac08e 100644 --- a/src/env/node/git/localGitProvider.ts +++ b/src/env/node/git/localGitProvider.ts @@ -1087,54 +1087,17 @@ export class LocalGitProvider implements GitProvider, Disposable { } @log() - async checkout( + async applyUnreachableCommitForPatch( repoPath: string, ref: string, - options?: { createBranch?: string } | { path?: string }, - ): Promise<void> { - const scope = getLogScope(); - - try { - await this.git.checkout(repoPath, ref, options); - this.container.events.fire('git:cache:reset', { repoPath: repoPath, caches: ['branches', 'status'] }); - } catch (ex) { - const msg: string = ex?.toString() ?? ''; - if (/overwritten by checkout/i.test(msg)) { - void showGenericErrorMessage( - `Unable to checkout '${ref}'. Please commit or stash your changes before switching branches`, - ); - return; - } - - Logger.error(ex, scope); - void showGenericErrorMessage(`Unable to checkout '${ref}'`); - } - } - - @log() - async clone(url: string, parentPath: string): Promise<string | undefined> { - const scope = getLogScope(); - - try { - return this.git.clone(url, parentPath); - } catch (ex) { - Logger.error(ex, scope); - void showGenericErrorMessage(`Unable to clone '${url}'`); - } - - return undefined; - } - - async applyPatchCommit( - repoPath: string, - patchCommitRef: string, options?: { branchName?: string; createBranchIfNeeded?: boolean; createWorktreePath?: string }, ): Promise<void> { const scope = getLogScope(); + // Stash any changes first - const repoStatus = await this.getStatusForRepo(repoPath); - const diffStatus = repoStatus?.getDiffStatus(); - if (diffStatus?.added || diffStatus?.deleted || diffStatus?.changed) { + const status = await this.getStatusForRepo(repoPath); + if (status?.files?.length) { + // TODO@eamodio we should probably prompt the user or provide a flag to prompt or not /cc @axosoft-ramint try { await this.git.stash__push(repoPath, undefined, { includeUntracked: true }); } catch (ex) { @@ -1153,6 +1116,7 @@ export class LocalGitProvider implements GitProvider, Disposable { const currentBranch = await this.getBranch(repoPath); const branchExists = options?.branchName == null || + currentBranch?.name === options.branchName || (await this.getBranches(repoPath, { filter: b => b.name === options.branchName }))?.values?.length > 0; const shouldCreate = options?.branchName != null && !branchExists && options.createBranchIfNeeded; @@ -1202,7 +1166,7 @@ export class LocalGitProvider implements GitProvider, Disposable { // Apply the patch using a cherry pick without committing try { - await this.git.cherrypick(targetPath, patchCommitRef, { noCommit: true, errors: GitErrorHandling.Throw }); + await this.git.cherrypick(targetPath, ref, { noCommit: true, errors: GitErrorHandling.Throw }); } catch (ex) { Logger.error(ex, scope); if (ex instanceof CherryPickError) { @@ -1223,6 +1187,45 @@ export class LocalGitProvider implements GitProvider, Disposable { void window.showInformationMessage(`Patch applied successfully`); } + @log() + async checkout( + repoPath: string, + ref: string, + options?: { createBranch?: string } | { path?: string }, + ): Promise<void> { + const scope = getLogScope(); + + try { + await this.git.checkout(repoPath, ref, options); + this.container.events.fire('git:cache:reset', { repoPath: repoPath, caches: ['branches', 'status'] }); + } catch (ex) { + const msg: string = ex?.toString() ?? ''; + if (/overwritten by checkout/i.test(msg)) { + void showGenericErrorMessage( + `Unable to checkout '${ref}'. Please commit or stash your changes before switching branches`, + ); + return; + } + + Logger.error(ex, scope); + void showGenericErrorMessage(`Unable to checkout '${ref}'`); + } + } + + @log() + async clone(url: string, parentPath: string): Promise<string | undefined> { + const scope = getLogScope(); + + try { + return this.git.clone(url, parentPath); + } catch (ex) { + Logger.error(ex, scope); + void showGenericErrorMessage(`Unable to clone '${url}'`); + } + + return undefined; + } + @log({ args: { 1: '<contents>', 3: '<message>' } }) async createUnreachableCommitForPatch( repoPath: string, diff --git a/src/git/gitProvider.ts b/src/git/gitProvider.ts index 3bae8ef..83a4e2b 100644 --- a/src/git/gitProvider.ts +++ b/src/git/gitProvider.ts @@ -138,17 +138,17 @@ export interface GitProvider extends Disposable { pruneRemote(repoPath: string, name: string): Promise<void>; removeRemote(repoPath: string, name: string): Promise<void>; applyChangesToWorkingFile(uri: GitUri, ref1?: string, ref2?: string): Promise<void>; + applyUnreachableCommitForPatch?( + repoPath: string, + ref: string, + options?: { branchName?: string; createBranchIfNeeded?: boolean; createWorktreePath?: string }, + ): Promise<void>; checkout( repoPath: string, ref: string, options?: { createBranch?: string | undefined } | { path?: string | undefined }, ): Promise<void>; clone?(url: string, parentPath: string): Promise<string | undefined>; - applyPatchCommit?( - repoPath: string, - patchCommitRef: string, - options?: { branchName?: string; createBranchIfNeeded?: boolean; createWorktreePath?: string }, - ): Promise<void>; createUnreachableCommitForPatch?( repoPath: string, contents: string, diff --git a/src/git/gitProviderService.ts b/src/git/gitProviderService.ts index a81038b..786b9e4 100644 --- a/src/git/gitProviderService.ts +++ b/src/git/gitProviderService.ts @@ -77,7 +77,6 @@ import type { GitTag, TagSortOptions } from './models/tag'; import type { GitTreeEntry } from './models/tree'; import type { GitUser } from './models/user'; import type { GitWorktree } from './models/worktree'; -import { parseGitRemoteUrl } from './parsers/remoteParser'; import type { RemoteProvider } from './remotes/remoteProvider'; import type { GitSearch, SearchQuery } from './search'; @@ -694,52 +693,6 @@ export class GitProviderService implements Disposable { return provider.discoverRepositories(uri, options); } - @log() - async findMatchingRepository(match: { firstSha?: string; remoteUrl?: string }): Promise<Repository | undefined> { - if (match.firstSha == null && match.remoteUrl == null) return undefined; - - let foundRepo; - - let remoteDomain = ''; - let remotePath = ''; - if (match.remoteUrl != null) { - [, remoteDomain, remotePath] = parseGitRemoteUrl(match.remoteUrl); - } - // Try to match a repo using the remote URL first, since that saves us some steps. - // As a fallback, try to match using the repo id. - for (const repo of this.container.git.repositories) { - if (remoteDomain != null && remotePath != null) { - const matchingRemotes = await repo.getRemotes({ - filter: r => r.matches(remoteDomain, remotePath), - }); - if (matchingRemotes.length > 0) { - foundRepo = repo; - break; - } - } - - if (match.firstSha != null && match.firstSha !== '-') { - // Repo ID can be any valid SHA in the repo, though standard practice is to use the - // first commit SHA. - if (await this.validateReference(repo.path, match.firstSha)) { - foundRepo = repo; - break; - } - } - } - - if (foundRepo == null && match.remoteUrl != null) { - const matchingLocalRepoPaths = await this.container.repositoryPathMapping.getLocalRepoPaths({ - remoteUrl: match.remoteUrl, - }); - if (matchingLocalRepoPaths.length > 0) { - foundRepo = await this.getOrOpenRepository(Uri.file(matchingLocalRepoPaths[0])); - } - } - - return foundRepo; - } - private _subscription: Subscription | undefined; private async getSubscription(): Promise<Subscription> { return this._subscription ?? (this._subscription = await this.container.subscription.getSubscription()); @@ -1330,6 +1283,16 @@ export class GitProviderService implements Disposable { } @log() + async applyUnreachableCommitForPatch( + repoPath: string | Uri, + ref: string, + options?: { branchName?: string; createBranchIfNeeded?: boolean; createWorktreePath?: string }, + ): Promise<void> { + const { provider, path } = this.getProvider(repoPath); + return provider.applyUnreachableCommitForPatch?.(path, ref, options); + } + + @log() checkout( repoPath: string | Uri, ref: string, @@ -1345,16 +1308,6 @@ export class GitProviderService implements Disposable { return provider.clone?.(url, parentPath); } - @log() - async applyPatchCommit( - repoPath: string | Uri, - patchCommitRef: string, - options?: { branchName?: string; createBranchIfNeeded?: boolean; createWorktreePath?: string }, - ): Promise<void> { - const { provider, path } = this.getProvider(repoPath); - return provider.applyPatchCommit?.(path, patchCommitRef, options); - } - @log({ args: { 1: '<contents>', 3: '<message>' } }) async createUnreachableCommitForPatch( repoPath: string | Uri, diff --git a/src/plus/webviews/patchDetails/patchDetailsWebview.ts b/src/plus/webviews/patchDetails/patchDetailsWebview.ts index 970fb80..f93455a 100644 --- a/src/plus/webviews/patchDetails/patchDetailsWebview.ts +++ b/src/plus/webviews/patchDetails/patchDetailsWebview.ts @@ -388,7 +388,7 @@ export class PatchDetailsWebviewProvider }; } - void this.container.git.applyPatchCommit(commit.repoPath, commit.ref, options); + void this.container.git.applyUnreachableCommitForPatch(commit.repoPath, commit.ref, options); } catch (ex) { void window.showErrorMessage(`Unable apply patch to '${patch.baseRef}': ${ex.message}`); }