Change:
<!-- Please search existing issues to avoid creating duplicates. --When downloading a GIT repository should indicate the percentage of download. <!-- Describe the feature you'd like. --
(Experimental duplicate detection) Thanks for submitting this issue. Please also check if it is already covered by an existing one, like: <!-- score: 0.484 --<!-- potentialduplicatescomment --
I would like to take this.

Discussion:
*  Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ <del> import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, MessageOptions, WorkspaceFolder } from 'vscode'; </del> <ins> import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, MessageOptions, WorkspaceFolder, Progress } from 'vscode'; </ins> import { Git, CommitOptions, Stash, ForcePushMode } from './git'; import { Repository, Resource, ResourceGroupType } from './repository'; import { Model } from './model';

const repositoryPath = await window.withProgress( opts, <del> (_, token) => this.git.clone(url!, parentPath, token) </del> <ins> (progress: Progress<{ message?: string, increment: number }>, token) => this.git.clone(url!, parentPath, progress, token) </ins> ); const choices = [];

import iconv = require('iconv-lite'); import * as filetype from 'file-type'; import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util'; <del> import { CancellationToken, Uri } from 'vscode'; </del> <ins> import { CancellationToken, Uri, Progress } from 'vscode'; import * as nls from 'vscode-nls'; </ins> import { detectEncoding } from './encoding'; import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status } from './api/git'; <ins> const localize = nls.loadMessageBundle(); </ins> const readfile = denodeify<string, string | null, string>(fs.readFile); export interface IGit {

encoding?: string; log?: boolean; cancellationToken?: CancellationToken; <ins> progress?: Progress<{ message?: string, increment: number }>; </ins> } <del> async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToken): Promise<IExecutionResult<Buffer>> { </del> <ins> async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToken, progress?: Progress<{ message?: string, increment: number }>): Promise<IExecutionResult<Buffer>> { </ins> if (!child.stdout || !child.stderr) { throw new GitError({ message: 'Failed to get stdout or stderr from git process.' }); }

disposables.push(toDisposable(() => ee.removeListener(name, fn))); }; <ins> const cloneProgressOutput = ['Receiving objects', 'Resolving deltas']; let prevInc = 0; </ins> let result = Promise.all<any>([ new Promise<number>((c, e) => { once(child, 'error', cpErrorHandler(e));

}), new Promise<string>(c => { const buffers: Buffer[] = []; <del> on(child.stderr, 'data', (b: Buffer) => buffers.push(b)); </del> <ins> 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; } } }); }); </ins> once(child.stderr, 'close', () => c(Buffer.concat(buffers).toString('utf8'))); }) ]) as Promise<[number, Buffer, string]>;

return; } <del> async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise<string> { </del> <ins> async clone(url: string, parentPath: string, progress: Progress<{ message?: string, increment: number }>, cancellationToken?: CancellationToken): Promise<string> { </ins> let baseFolderName = decodeURI(url).replace(/^.*//, '').replace(/.git$/, '') || 'repository'; let folderName = baseFolderName; let folderPath = path.join(parentPath, folderName);

await mkdirp(parentPath); try { <del> await this.exec(parentPath, ['clone', url.includes(' ') ? encodeURI(url) : url, folderPath], { cancellationToken }); </del> <ins> await this.exec(parentPath, ['clone', url.includes(' ') ? encodeURI(url) : url, folderPath, '--progress'], { cancellationToken, progress }); </ins> } catch (err) { if (err.stderr) { err.stderr = err.stderr.replace(/^Cloning.+$/m, '').trim();

child.stdin.end(options.input, 'utf8'); } <del> const bufferResult = await exec(child, options.cancellationToken); </del> <ins> const bufferResult = await exec(child, options.cancellationToken, options.progress); </ins> if (options.log !== false && bufferResult.stderr.length > 0) { this.log(`${bufferResult.stderr}n`);