提交 471b263c 编写于 作者: J Joao Moreno

Merge commit 'refs/pull/71341/head' of github.com:microsoft/vscode into pr/71341

...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, MessageOptions, WorkspaceFolder } from 'vscode'; import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, MessageOptions, WorkspaceFolder, Progress } from 'vscode';
import { Git, CommitOptions, Stash, ForcePushMode } from './git'; import { Git, CommitOptions, Stash, ForcePushMode } from './git';
import { Repository, Resource, ResourceGroupType } from './repository'; import { Repository, Resource, ResourceGroupType } from './repository';
import { Model } from './model'; import { Model } from './model';
...@@ -493,7 +493,7 @@ export class CommandCenter { ...@@ -493,7 +493,7 @@ export class CommandCenter {
const repositoryPath = await window.withProgress( const repositoryPath = await window.withProgress(
opts, opts,
(_, token) => this.git.clone(url!, parentPath, token) (progress: Progress<{ message?: string, increment: number }>, token) => this.git.clone(url!, parentPath, progress, token)
); );
let message = localize('proposeopen', "Would you like to open the cloned repository?"); let message = localize('proposeopen', "Would you like to open the cloned repository?");
......
...@@ -12,10 +12,13 @@ import { EventEmitter } from 'events'; ...@@ -12,10 +12,13 @@ import { EventEmitter } from 'events';
import iconv = require('iconv-lite'); import iconv = require('iconv-lite');
import * as filetype from 'file-type'; import * as filetype from 'file-type';
import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter } from './util'; import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter } from './util';
import { CancellationToken } from 'vscode'; import { CancellationToken, Progress } from 'vscode';
import { URI } from 'vscode-uri'; import { URI } from 'vscode-uri';
import { detectEncoding } from './encoding'; import { detectEncoding } from './encoding';
import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status } from './api/git'; import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status } from './api/git';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
// https://github.com/microsoft/vscode/issues/65693 // https://github.com/microsoft/vscode/issues/65693
const MAX_CLI_LENGTH = 30000; const MAX_CLI_LENGTH = 30000;
...@@ -163,9 +166,10 @@ export interface SpawnOptions extends cp.SpawnOptions { ...@@ -163,9 +166,10 @@ export interface SpawnOptions extends cp.SpawnOptions {
encoding?: string; encoding?: string;
log?: boolean; log?: boolean;
cancellationToken?: CancellationToken; cancellationToken?: CancellationToken;
progress?: Progress<{ message?: string, increment: number }>;
} }
async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToken): Promise<IExecutionResult<Buffer>> { async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToken, progress?: Progress<{ message?: string, increment: number }>): Promise<IExecutionResult<Buffer>> {
if (!child.stdout || !child.stderr) { if (!child.stdout || !child.stderr) {
throw new GitError({ message: 'Failed to get stdout or stderr from git process.' }); throw new GitError({ message: 'Failed to get stdout or stderr from git process.' });
} }
...@@ -186,6 +190,9 @@ async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToke ...@@ -186,6 +190,9 @@ async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToke
disposables.push(toDisposable(() => ee.removeListener(name, fn))); disposables.push(toDisposable(() => ee.removeListener(name, fn)));
}; };
const cloneProgressOutput = ['Receiving objects', 'Resolving deltas'];
let prevInc = 0;
let result = Promise.all<any>([ let result = Promise.all<any>([
new Promise<number>((c, e) => { new Promise<number>((c, e) => {
once(child, 'error', cpErrorHandler(e)); once(child, 'error', cpErrorHandler(e));
...@@ -198,7 +205,27 @@ async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToke ...@@ -198,7 +205,27 @@ async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToke
}), }),
new Promise<string>(c => { new Promise<string>(c => {
const buffers: Buffer[] = []; const buffers: Buffer[] = [];
on(child.stderr, 'data', (b: Buffer) => buffers.push(b)); on(child.stderr, 'data', (b: Buffer) => {
buffers.push(b);
const s = b.toString();
// Check for git clone progress reporting
cloneProgressOutput.forEach(cloneOutput => {
if (s.startsWith(cloneOutput)) {
const idx = s.indexOf('%');
const inc = parseInt(s.slice(idx - 3, idx));
if (progress) {
progress.report({
message: localize(cloneOutput.toLowerCase(), cloneOutput) + ': ' + inc + '%',
increment: inc - prevInc
});
prevInc = inc;
}
}
});
});
once(child.stderr, 'close', () => c(Buffer.concat(buffers).toString('utf8'))); once(child.stderr, 'close', () => c(Buffer.concat(buffers).toString('utf8')));
}) })
]) as Promise<[number, Buffer, string]>; ]) as Promise<[number, Buffer, string]>;
...@@ -341,7 +368,7 @@ export class Git { ...@@ -341,7 +368,7 @@ export class Git {
return; return;
} }
async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise<string> { async clone(url: string, parentPath: string, progress: Progress<{ message?: string, increment: number }>, cancellationToken?: CancellationToken): Promise<string> {
let baseFolderName = decodeURI(url).replace(/[\/]+$/, '').replace(/^.*[\/\\]/, '').replace(/\.git$/, '') || 'repository'; let baseFolderName = decodeURI(url).replace(/[\/]+$/, '').replace(/^.*[\/\\]/, '').replace(/\.git$/, '') || 'repository';
let folderName = baseFolderName; let folderName = baseFolderName;
let folderPath = path.join(parentPath, folderName); let folderPath = path.join(parentPath, folderName);
...@@ -355,7 +382,7 @@ export class Git { ...@@ -355,7 +382,7 @@ export class Git {
await mkdirp(parentPath); await mkdirp(parentPath);
try { try {
await this.exec(parentPath, ['clone', url.includes(' ') ? encodeURI(url) : url, folderPath], { cancellationToken }); await this.exec(parentPath, ['clone', url.includes(' ') ? encodeURI(url) : url, folderPath, '--progress'], { cancellationToken, progress });
} catch (err) { } catch (err) {
if (err.stderr) { if (err.stderr) {
err.stderr = err.stderr.replace(/^Cloning.+$/m, '').trim(); err.stderr = err.stderr.replace(/^Cloning.+$/m, '').trim();
...@@ -405,7 +432,7 @@ export class Git { ...@@ -405,7 +432,7 @@ export class Git {
child.stdin.end(options.input, 'utf8'); child.stdin.end(options.input, 'utf8');
} }
const bufferResult = await exec(child, options.cancellationToken); const bufferResult = await exec(child, options.cancellationToken, options.progress);
if (options.log !== false && bufferResult.stderr.length > 0) { if (options.log !== false && bufferResult.stderr.length > 0) {
this.log(`${bufferResult.stderr}\n`); this.log(`${bufferResult.stderr}\n`);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册