Parcourir la source

Fixes #2660 use git location for terminal run cmds

main
Eric Amodio il y a 1 an
Parent
révision
039d611845
7 fichiers modifiés avec 96 ajouts et 31 suppressions
  1. +32
    -1
      src/env/node/git/git.ts
  2. +16
    -1
      src/env/node/git/localGitProvider.ts
  3. +14
    -1
      src/env/node/git/shell.ts
  4. +9
    -1
      src/git/gitProvider.ts
  5. +11
    -0
      src/git/gitProviderService.ts
  6. +13
    -15
      src/git/models/repository.ts
  7. +1
    -12
      src/terminal.ts

+ 32
- 1
src/env/node/git/git.ts Voir le fichier

@ -17,15 +17,19 @@ import { GitLogParser } from '../../../git/parsers/logParser';
import { GitReflogParser } from '../../../git/parsers/reflogParser';
import { GitTagParser } from '../../../git/parsers/tagParser';
import { splitAt } from '../../../system/array';
import { configuration } from '../../../system/configuration';
import { join } from '../../../system/iterable';
import { Logger } from '../../../system/logger';
import { LogLevel, slowCallWarningThreshold } from '../../../system/logger.constants';
import { dirname, isAbsolute, isFolderGlob, joinPaths, normalizePath, splitPath } from '../../../system/path';
import { getDurationMilliseconds } from '../../../system/string';
import { getEditorCommand } from '../../../system/utils';
import { compare, fromString } from '../../../system/version';
import { ensureGitTerminal } from '../../../terminal';
import { isWindows } from '../platform';
import type { GitLocation } from './locator';
import type { RunOptions } from './shell';
import { fsExists, run, RunError } from './shell';
import { fsExists, getWindowsShortPath, run, RunError } from './shell';
const emptyArray = Object.freeze([]) as unknown as any[];
const emptyObj = Object.freeze({});
@ -2045,6 +2049,33 @@ export class Git {
}
}
async runCommandViaTerminal(cwd: string, command: string, args: string[], options?: { execute?: boolean }) {
const location = await this.getLocation();
const git = location.path ?? 'git';
const coreEditorConfig = configuration.get('terminal.overrideGitEditor')
? `-c "core.editor=${getEditorCommand()}" `
: '';
const parsedArgs = args.map(arg => (arg.startsWith('#') || /['();$|>&<]/.test(arg) ? `"${arg}"` : arg));
let text;
if (git.includes(' ') && isWindows) {
const shortenedPath = await getWindowsShortPath(git);
text = `${shortenedPath} -C "${cwd}" ${coreEditorConfig}${command} ${parsedArgs.join(' ')}`;
} else {
text = `${git.includes(' ') ? `"${git}"` : git} -C "${cwd}" ${coreEditorConfig}${command} ${parsedArgs.join(
' ',
)}`;
}
this.logGitCommand(`[TERM] ${text}`, 0);
const terminal = ensureGitTerminal();
terminal.show(false);
terminal.sendText(text, options?.execute ?? false);
}
private _gitOutput: OutputChannel | undefined;
private logGitCommand(command: string, duration: number, ex?: Error): void {

+ 16
- 1
src/env/node/git/localGitProvider.ts Voir le fichier

@ -369,7 +369,9 @@ export class LocalGitProvider implements GitProvider, Disposable {
} else {
Logger.log(
scope,
`Git (${location.version}) found in ${location.path === 'git' ? 'PATH' : location.path} [${getDurationMilliseconds(start)}ms]`,
`Git (${location.version}) found in ${
location.path === 'git' ? 'PATH' : location.path
} [${getDurationMilliseconds(start)}ms]`,
);
}
@ -4660,6 +4662,19 @@ export class LocalGitProvider implements GitProvider, Disposable {
}
}
@log({ args: { 2: false } })
async runGitCommandViaTerminal(
repoPath: string,
command: string,
args: string[],
options?: { execute?: boolean },
): Promise<void> {
await this.git.runCommandViaTerminal(repoPath, command, args, options);
// Right now we are reliant on the Repository class to fire the change event (as a stop gap if we don't detect a change through the normal mechanisms)
// setTimeout(() => this.fireChange(RepositoryChange.Unknown), 2500);
}
@log()
validateBranchOrTagName(repoPath: string, ref: string): Promise<boolean> {
return this.git.check_ref_format(ref, repoPath);

+ 14
- 1
src/env/node/git/shell.ts Voir le fichier

@ -1,5 +1,5 @@
import type { ExecException } from 'child_process';
import { execFile } from 'child_process';
import { exec, execFile } from 'child_process';
import type { Stats } from 'fs';
import { exists, existsSync, statSync } from 'fs';
import { join as joinPaths } from 'path';
@ -116,6 +116,19 @@ export function findExecutable(exe: string, args: string[]): { cmd: string; args
return { cmd: exe, args: args };
}
export async function getWindowsShortPath(path: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
exec(`for %I in ("${path}") do @echo %~sI`, (error, stdout, _stderr) => {
if (error != null) {
reject(error);
return;
}
resolve(stdout.trim().replace(/\\/g, '/'));
});
});
}
export interface RunOptions<TEncoding = BufferEncoding | 'buffer'> {
cancellation?: CancellationToken;
cwd?: string;

+ 9
- 1
src/git/gitProvider.ts Voir le fichier

@ -437,7 +437,7 @@ export interface GitProvider extends Disposable {
},
): Promise<GitLog | undefined>;
searchCommits(
repoPath: string | Uri,
repoPath: string,
search: SearchQuery,
options?: {
cancellation?: CancellationToken;
@ -445,6 +445,14 @@ export interface GitProvider extends Disposable {
ordering?: 'date' | 'author-date' | 'topo';
},
): Promise<GitSearch>;
runGitCommandViaTerminal?(
repoPath: string,
command: string,
args: string[],
options?: { execute?: boolean },
): Promise<void>;
validateBranchOrTagName(repoPath: string, ref: string): Promise<boolean>;
validateReference(repoPath: string, ref: string): Promise<boolean>;

+ 11
- 0
src/git/gitProviderService.ts Voir le fichier

@ -2649,6 +2649,17 @@ export class GitProviderService implements Disposable {
return provider.searchCommits(path, search, options);
}
@log({ args: false })
async runGitCommandViaTerminal(
repoPath: string | Uri,
command: string,
args: string[],
options?: { execute?: boolean },
): Promise<void> {
const { provider, path } = this.getProvider(repoPath);
return provider.runGitCommandViaTerminal?.(path, command, args, options);
}
@log()
validateBranchOrTagName(repoPath: string | Uri, ref: string): Promise<boolean> {
const { provider, path } = this.getProvider(repoPath);

+ 13
- 15
src/git/models/repository.ts Voir le fichier

@ -21,7 +21,6 @@ import { getLoggableName, Logger } from '../../system/logger';
import { getLogScope } from '../../system/logger.scope';
import { updateRecordValue } from '../../system/object';
import { basename, normalizePath } from '../../system/path';
import { runGitCommandInTerminal } from '../../terminal';
import type { GitDir, GitProviderDescriptor, GitRepositoryCaches } from '../gitProvider';
import type { RemoteProviders } from '../remotes/remoteProviders';
import { loadRemoteProviders } from '../remotes/remoteProviders';
@ -490,7 +489,7 @@ export class Repository implements Disposable {
@log()
branch(...args: string[]) {
this.runTerminalCommand('branch', ...args);
void this.runTerminalCommand('branch', ...args);
}
@log()
@ -505,7 +504,7 @@ export class Repository implements Disposable {
if (options?.force) {
args.push('--force');
}
this.runTerminalCommand('branch', ...args, ...branches.map(b => b.ref));
void this.runTerminalCommand('branch', ...args, ...branches.map(b => b.ref));
if (options?.remote) {
const trackingBranches = localBranches.filter(b => b.upstream != null);
@ -515,7 +514,7 @@ export class Repository implements Disposable {
);
for (const [remote, branches] of branchesByOrigin.entries()) {
this.runTerminalCommand(
void this.runTerminalCommand(
'push',
'-d',
remote,
@ -531,14 +530,14 @@ export class Repository implements Disposable {
const branchesByOrigin = groupByMap(remoteBranches, b => getRemoteNameFromBranchName(b.name));
for (const [remote, branches] of branchesByOrigin.entries()) {
this.runTerminalCommand('push', '-d', remote, ...branches.map(b => getNameWithoutRemote(b)));
void this.runTerminalCommand('push', '-d', remote, ...branches.map(b => getNameWithoutRemote(b)));
}
}
}
@log()
cherryPick(...args: string[]) {
this.runTerminalCommand('cherry-pick', ...args);
void this.runTerminalCommand('cherry-pick', ...args);
}
containsUri(uri: Uri) {
@ -782,7 +781,7 @@ export class Repository implements Disposable {
@log()
merge(...args: string[]) {
this.runTerminalCommand('merge', ...args);
void this.runTerminalCommand('merge', ...args);
}
@gate()
@ -923,7 +922,7 @@ export class Repository implements Disposable {
@log()
rebase(configs: string[] | undefined, ...args: string[]) {
this.runTerminalCommand(
void this.runTerminalCommand(
configs != null && configs.length !== 0 ? `${configs.join(' ')} rebase` : 'rebase',
...args,
);
@ -931,7 +930,7 @@ export class Repository implements Disposable {
@log()
reset(...args: string[]) {
this.runTerminalCommand('reset', ...args);
void this.runTerminalCommand('reset', ...args);
}
@log({ singleLine: true })
@ -965,7 +964,7 @@ export class Repository implements Disposable {
@log()
revert(...args: string[]) {
this.runTerminalCommand('revert', ...args);
void this.runTerminalCommand('revert', ...args);
}
@debug()
@ -1128,7 +1127,7 @@ export class Repository implements Disposable {
@log()
tag(...args: string[]) {
this.runTerminalCommand('tag', ...args);
void this.runTerminalCommand('tag', ...args);
}
@log()
@ -1138,7 +1137,7 @@ export class Repository implements Disposable {
}
const args = ['--delete'];
this.runTerminalCommand('tag', ...args, ...tags.map(t => t.ref));
void this.runTerminalCommand('tag', ...args, ...tags.map(t => t.ref));
}
@debug()
@ -1217,9 +1216,8 @@ export class Repository implements Disposable {
this._onDidChangeFileSystem.fire(e);
}
private runTerminalCommand(command: string, ...args: string[]) {
const parsedArgs = args.map(arg => (arg.startsWith('#') || /['();$|>&<]/.test(arg) ? `"${arg}"` : arg));
runGitCommandInTerminal(command, parsedArgs.join(' '), this.path, true);
private async runTerminalCommand(command: string, ...args: string[]) {
await this.container.git.runGitCommandViaTerminal?.(this.uri, command, args, { execute: true });
setTimeout(() => this.fireChange(RepositoryChange.Unknown), 2500);
}

+ 1
- 12
src/terminal.ts Voir le fichier

@ -1,15 +1,13 @@
import type { Disposable, Terminal } from 'vscode';
import { window } from 'vscode';
import { Container } from './container';
import { configuration } from './system/configuration';
import { getEditorCommand } from './system/utils';
let _terminal: Terminal | undefined;
let _disposable: Disposable | undefined;
const extensionTerminalName = 'GitLens';
function ensureTerminal(): Terminal {
export function ensureGitTerminal(): Terminal {
if (_terminal == null) {
_terminal = window.createTerminal(extensionTerminalName);
_disposable = window.onDidCloseTerminal((e: Terminal) => {
@ -25,12 +23,3 @@ function ensureTerminal(): Terminal {
return _terminal;
}
export function runGitCommandInTerminal(command: string, args: string, cwd: string, execute: boolean = false) {
const terminal = ensureTerminal();
terminal.show(false);
const coreEditorConfig = configuration.get('terminal.overrideGitEditor')
? `-c "core.editor=${getEditorCommand()}" `
: '';
terminal.sendText(`git -C "${cwd}" ${coreEditorConfig}${command} ${args}`, execute);
}

Chargement…
Annuler
Enregistrer