From 8b2779dc0952101a8f806f987615c33f2d5d516b Mon Sep 17 00:00:00 2001 From: Sergio Date: Wed, 25 Sep 2024 17:07:50 +0200 Subject: [PATCH] add branchCreate and branchRename methods --- CHANGELOG.md | 2 +- src/commands/git/branch.ts | 4 +-- src/env/node/git/git.ts | 4 +++ src/env/node/git/localGitProvider.ts | 14 ++++++++ src/git/gitProvider.ts | 13 +++++++ src/git/gitProviderService.ts | 34 +++++++++++++++++++ src/git/models/repository.ts | 7 ++-- .../providers/github/githubGitProvider.ts | 4 +++ 8 files changed, 74 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4fa991b1ccc2..fab6f06cfaec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ### Changed - Adds vscode-test to run unit-tests — closes [#3570](https://github.com/gitkraken/vscode-gitlens/issues/3570) - +- Change `branch create` and `branch rename` terminal-run commands into normal commands ### Fixed - Fixes [#3592](https://github.com/gitkraken/vscode-gitlens/issues/3592) - Connecting to an integration via Remotes view (but likely others) doesn't work diff --git a/src/commands/git/branch.ts b/src/commands/git/branch.ts index b6938ca8cea9b..448d3c485adc8 100644 --- a/src/commands/git/branch.ts +++ b/src/commands/git/branch.ts @@ -393,7 +393,7 @@ export class BranchGitCommand extends QuickCommand { if (state.flags.includes('--switch')) { await state.repo.switch(state.reference.ref, { createBranch: state.name }); } else { - state.repo.branch(...state.flags, state.name, state.reference.ref); + await state.repo.git.branchCreate(state.name, state.reference.ref); } } } @@ -614,7 +614,7 @@ export class BranchGitCommand extends QuickCommand { state.flags = result; endSteps(state); - state.repo.branch(...state.flags, state.reference.ref, state.name); + await state.repo.git.branchRename(state.reference.ref, state.name); } } diff --git a/src/env/node/git/git.ts b/src/env/node/git/git.ts index 3bbba673336bc..b4c0904884173 100644 --- a/src/env/node/git/git.ts +++ b/src/env/node/git/git.ts @@ -506,6 +506,10 @@ export class Git { } } + branch(repoPath: string, ...args: string[]) { + return this.git({ cwd: repoPath }, 'branch', ...args); + } + branch__set_upstream(repoPath: string, branch: string, remote: string, remoteBranch: string) { return this.git({ cwd: repoPath }, 'branch', '--set-upstream-to', `${remote}/${remoteBranch}`, branch); } diff --git a/src/env/node/git/localGitProvider.ts b/src/env/node/git/localGitProvider.ts index f2376700628ee..0e59cc529e6e4 100644 --- a/src/env/node/git/localGitProvider.ts +++ b/src/env/node/git/localGitProvider.ts @@ -39,6 +39,7 @@ import { WorktreeDeleteErrorReason, } from '../../../git/errors'; import type { + GitBranchOptions, GitCaches, GitDir, GitProvider, @@ -1230,6 +1231,19 @@ export class LocalGitProvider implements GitProvider, Disposable { } } + @log() + async branch(repoPath: string, options: GitBranchOptions): Promise { + if (options?.create != null) { + return this.git.branch(repoPath, options.create.name, options.create.startRef); + } + + if (options?.rename != null) { + return this.git.branch(repoPath, '-m', options.rename.old, options.rename.new); + } + + throw new Error('Invalid branch options'); + } + @log() async checkout( repoPath: string, diff --git a/src/git/gitProvider.ts b/src/git/gitProvider.ts index 5e0c74bd1d29d..465acff80e8a6 100644 --- a/src/git/gitProvider.ts +++ b/src/git/gitProvider.ts @@ -112,6 +112,17 @@ export interface RepositoryVisibilityInfo { remotesHash?: string; } +export type GitBranchOptions = { + rename?: { + old: string; + new: string; + }; + create?: { + name: string; + startRef: string; + }; +}; + export interface GitProviderRepository { addRemote(repoPath: string, name: string, url: string, options?: { fetch?: boolean }): Promise; pruneRemote(repoPath: string, name: string): Promise; @@ -126,6 +137,7 @@ export interface GitProviderRepository { stash?: boolean | 'prompt'; }, ): Promise; + checkout( repoPath: string, ref: string, @@ -477,6 +489,7 @@ export interface GitProvider extends GitProviderRepository, Disposable { getWorkingUri(repoPath: string, uri: Uri): Promise; applyChangesToWorkingFile(uri: GitUri, ref1?: string, ref2?: string): Promise; + branch(_repoPath: string, _options: GitBranchOptions): Promise; clone?(url: string, parentPath: string): Promise; /** * Returns the blame of a file diff --git a/src/git/gitProviderService.ts b/src/git/gitProviderService.ts index 382253d624719..cb30bc052d338 100644 --- a/src/git/gitProviderService.ts +++ b/src/git/gitProviderService.ts @@ -18,6 +18,7 @@ import type { SearchQuery } from '../constants.search'; import type { Container } from '../container'; import { AccessDeniedError, CancellationError, ProviderNotFoundError } from '../errors'; import type { FeatureAccess, Features, PlusFeatures, RepoFeatureAccess } from '../features'; +import { showGenericErrorMessage } from '../messages'; import { getApplicablePromo } from '../plus/gk/account/promos'; import type { Subscription } from '../plus/gk/account/subscription'; import { isSubscriptionPaidPlan, SubscriptionPlanId } from '../plus/gk/account/subscription'; @@ -43,6 +44,7 @@ import { configuration } from '../system/vscode/configuration'; import { setContext } from '../system/vscode/context'; import { getBestPath } from '../system/vscode/path'; import type { + GitBranchOptions, GitCaches, GitDir, GitProvider, @@ -1325,6 +1327,38 @@ export class GitProviderService implements Disposable { return provider.applyUnreachableCommitForPatch?.(path, ref, options); } + @log() + branchCreate(repoPath: string, name: string, startRef: string): Promise { + const { provider, path } = this.getProvider(repoPath); + try { + return provider.branch(path, { + create: { + name: name, + startRef: startRef, + }, + }); + } catch (ex) { + Logger.error(ex); + return showGenericErrorMessage('Unable to create branch'); + } + } + + @log() + branchRename(repoPath: string, oldName: string, newName: string): Promise { + const { provider, path } = this.getProvider(repoPath); + try { + return provider.branch(path, { + rename: { + old: oldName, + new: newName, + }, + }); + } catch (ex) { + Logger.error(ex); + return showGenericErrorMessage('Unable to rename branch'); + } + } + @log() checkout( repoPath: string | Uri, diff --git a/src/git/models/repository.ts b/src/git/models/repository.ts index c4e70b7746852..96e0cb85b817c 100644 --- a/src/git/models/repository.ts +++ b/src/git/models/repository.ts @@ -39,6 +39,8 @@ export type RepoGitProviderService = Pick< [K in keyof GitProviderService]: RemoveFirstArg; }, | keyof GitProviderRepository + | 'branchCreate' + | 'branchRename' | 'getBestRemoteWithIntegration' | 'getBranch' | 'getRemote' @@ -560,11 +562,6 @@ export class Repository implements Disposable { return remote; } - @log() - branch(...args: string[]) { - void this.runTerminalCommand('branch', ...args); - } - @log() branchDelete(branches: GitBranchReference | GitBranchReference[], options?: { force?: boolean; remote?: boolean }) { if (!Array.isArray(branches)) { diff --git a/src/plus/integrations/providers/github/githubGitProvider.ts b/src/plus/integrations/providers/github/githubGitProvider.ts index b33fdad449cea..bddbf929e9eef 100644 --- a/src/plus/integrations/providers/github/githubGitProvider.ts +++ b/src/plus/integrations/providers/github/githubGitProvider.ts @@ -25,6 +25,7 @@ import { import { Features } from '../../../../features'; import { GitSearchError } from '../../../../git/errors'; import type { + GitBranchOptions, GitCaches, GitProvider, LeftRightCommitCountResult, @@ -456,6 +457,9 @@ export class GitHubGitProvider implements GitProvider, Disposable { @log() async applyChangesToWorkingFile(_uri: GitUri, _ref1?: string, _ref2?: string): Promise {} + @log() + async branch(_repoPath: string, _options: GitBranchOptions): Promise {} + @log() async branchContainsCommit(_repoPath: string, _name: string, _ref: string): Promise { return false;