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}`);
 			}