Browse Source

Fixes #1183 - allow stashing lots of files or warn

main
Eric Amodio 4 years ago
parent
commit
3509a3a247
5 changed files with 55 additions and 14 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +1
    -1
      src/commands/git/stash.ts
  3. +19
    -6
      src/git/git.ts
  4. +26
    -7
      src/git/gitService.ts
  5. +8
    -0
      src/system/array.ts

+ 1
- 0
CHANGELOG.md View File

@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
### Fixed
- Fixes [#1183](https://github.com/eamodio/vscode-gitlens/issues/1183) - stash all changes has no effect when the number of files is large
- Fixes [#1308](https://github.com/eamodio/vscode-gitlens/issues/1308) - Escape quotes for PRs titles
- Fixes [#1309](https://github.com/eamodio/vscode-gitlens/issues/1309) - "Fetch" not working on remote branches
- Fixes an issue where many views wouldn't refresh properly when going from no items to some items

+ 1
- 1
src/commands/git/stash.ts View File

@ -496,7 +496,7 @@ export class StashGitCommand extends QuickCommand {
} catch (ex) {
Logger.error(ex, context.title);
const msg: string = ex?.toString() ?? '';
const msg: string = ex?.message ?? ex?.toString() ?? '';
if (msg.includes('newer version of Git')) {
void window.showErrorMessage(`Unable to stash changes. ${msg}`);

+ 19
- 6
src/git/git.ts View File

@ -25,6 +25,7 @@ export type GitDiffFilter = 'A' | 'C' | 'D' | 'M' | 'R' | 'T' | 'U' | 'X' | 'B'
const emptyArray = (Object.freeze([]) as any) as any[];
const emptyObj = Object.freeze({});
const emptyStr = '';
export const maxGitCliLength = 30000;
const slash = '/';
const textDecoder = new TextDecoder('utf8');
@ -1308,18 +1309,19 @@ export namespace Git {
);
}
export function stash__push(
export async function stash__push(
repoPath: string,
message?: string,
{
includeUntracked,
keepIndex,
pathspecs,
}: { includeUntracked?: boolean; keepIndex?: boolean; pathspecs?: string[] } = {},
) {
stdin,
}: { includeUntracked?: boolean; keepIndex?: boolean; pathspecs?: string[]; stdin?: boolean } = {},
): Promise<void> {
const params = ['stash', 'push'];
if (includeUntracked || (pathspecs !== undefined && pathspecs.length !== 0)) {
if (includeUntracked || (pathspecs != null && pathspecs.length !== 0)) {
params.push('-u');
}
@ -1331,12 +1333,23 @@ export namespace Git {
params.push('-m', message);
}
if (stdin && pathspecs != null && pathspecs.length !== 0) {
void (await git<string>(
{ cwd: repoPath, stdin: pathspecs.join('\0') },
...params,
'--pathspec-from-file=-',
'--pathspec-file-nul',
));
return;
}
params.push('--');
if (pathspecs !== undefined && pathspecs.length !== 0) {
if (pathspecs != null && pathspecs.length !== 0) {
params.push(...pathspecs);
}
return git<string>({ cwd: repoPath }, ...params);
void (await git<string>({ cwd: repoPath }, ...params));
}
export function status(

+ 26
- 7
src/git/gitService.ts View File

@ -66,6 +66,7 @@ import {
GitTagParser,
GitTree,
GitTreeParser,
maxGitCliLength,
PullRequest,
PullRequestDateFormatting,
PullRequestState,
@ -3897,21 +3898,39 @@ export class GitService implements Disposable {
) {
if (uris == null) return Git.stash__push(repoPath, message, options);
GitService.ensureGitVersion('2.13.2', 'Stashing individual files');
GitService.ensureGitVersion(
'2.13.2',
'Stashing individual files',
' Please retry by stashing everything or install a more recent version of Git.',
);
const pathspecs = uris.map(u => `./${Git.splitPath(u.fsPath, repoPath)[0]}`);
return Git.stash__push(repoPath, message, { ...options, pathspecs: pathspecs });
const stdinVersion = '2.30.0';
const stdin = GitService.compareGitVersion(stdinVersion) !== -1;
// If we don't support stdin, then error out if we are over the maximum allowed git cli length
if (!stdin && Arrays.countStringLength(pathspecs) > maxGitCliLength) {
GitService.ensureGitVersion(
stdinVersion,
`Stashing so many files (${pathspecs.length}) at once`,
' Please retry by stashing fewer files or install a more recent version of Git.',
);
}
return Git.stash__push(repoPath, message, {
...options,
pathspecs: pathspecs,
stdin: stdin,
});
}
static compareGitVersion(version: string) {
return Versions.compare(Versions.fromString(Git.getGitVersion()), Versions.fromString(version));
}
static ensureGitVersion(version: string, feature: string): void {
const gitVersion = Git.getGitVersion();
if (Versions.compare(Versions.fromString(gitVersion), Versions.fromString(version)) === -1) {
static ensureGitVersion(version: string, prefix: string, suffix: string): void {
if (GitService.compareGitVersion(version) === -1) {
throw new Error(
`${feature} requires a newer version of Git (>= ${version}) than is currently installed (${gitVersion}). Please install a more recent version of Git to use this GitLens feature.`,
`${prefix} requires a newer version of Git (>= ${version}) than is currently installed (${Git.getGitVersion()}).${suffix}`,
);
}
}

+ 8
- 0
src/system/array.ts View File

@ -17,6 +17,14 @@ export function chunk(source: T[], size: number): T[][] {
return chunks;
}
export function countStringLength(source: string[]): number {
let length = 0;
for (const s of source) {
length += s.length;
}
return length;
}
export function countUniques<T>(source: T[], accessor: (item: T) => string): Record<string, number> {
const uniqueCounts = Object.create(null) as Record<string, number>;
for (const item of source) {

Loading…
Cancel
Save