Skip to content

Commit 1ae014e

Browse files
committed
Fixes applying changes for adds and untracked files
1 parent 0e3ecee commit 1ae014e

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
3636
- Fixes [#588](https://github.com/eamodio/vscode-gitlens/issues/588) — Output channel doesn't exist with `gitlens.outputLevel` default
3737
- Fixes an issue where comparing a file with its staged revision doesn't show any content
3838
- Fixes an issue where the workspace folder added by the _Explore Repository from Here_ command (`gitlens.views.exploreRepoRevision`) would fail to load in certain cases
39+
- Fixes an issue where applying changes of an added file or an untracked file (in a stash) would fail
3940

4041
## [9.0.3] - 2018-12-06
4142

src/git/git.ts

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ export * from './models/models';
1313
export * from './parsers/parsers';
1414
export * from './remotes/provider';
1515

16+
// This is a root sha of all git repo's if using sha1
17+
const rootSha = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
18+
1619
const defaultBlameParams = ['blame', '--root', '--incremental'];
1720

1821
// Using %x00 codes because some shells seem to try to expand things if not
@@ -52,7 +55,7 @@ const stashFormat = [
5255
const defaultStashParams = ['stash', 'list', '--name-status', '-M', `--format=${stashFormat}`];
5356

5457
const GitErrors = {
55-
badRevision: /bad revision \'.*?\'/i,
58+
badRevision: /bad revision \'(.*?)\'/i,
5659
notAValidObjectName: /Not a valid object name/i
5760
};
5861

@@ -477,22 +480,52 @@ export class Git {
477480
return data.length === 0 ? undefined : data.trim();
478481
}
479482

480-
static diff(repoPath: string, fileName: string, ref1?: string, ref2?: string, options: { encoding?: string } = {}) {
481-
const params = ['diff', '--diff-filter=M', '-M', '--no-ext-diff', '--minimal'];
483+
static async diff(
484+
repoPath: string,
485+
fileName: string,
486+
ref1?: string,
487+
ref2?: string,
488+
options: { encoding?: string; filter?: string } = {}
489+
): Promise<string> {
490+
const params = ['diff', '-M', '--no-ext-diff', '--minimal'];
491+
if (options.filter) {
492+
params.push(`--diff-filter=${options.filter}`);
493+
}
494+
482495
if (ref1) {
496+
// <sha>^3 signals an untracked file in a stash and if we are trying to find its parent, use the root sha
497+
if (ref1.endsWith('^3^')) {
498+
ref1 = rootSha;
499+
}
483500
params.push(Git.isStagedUncommitted(ref1) ? '--staged' : ref1);
484501
}
485502
if (ref2) {
486503
params.push(Git.isStagedUncommitted(ref2) ? '--staged' : ref2);
487504
}
488505

489506
const encoding: BufferEncoding = options.encoding === 'utf8' ? 'utf8' : 'binary';
490-
return git<string>(
491-
{ cwd: repoPath, configs: ['-c', 'color.diff=false'], encoding: encoding },
492-
...params,
493-
'--',
494-
fileName
495-
);
507+
508+
try {
509+
return await git<string>(
510+
{ cwd: repoPath, configs: ['-c', 'color.diff=false'], encoding: encoding },
511+
...params,
512+
'--',
513+
fileName
514+
);
515+
}
516+
catch (ex) {
517+
const match = GitErrors.badRevision.exec(ex.message);
518+
if (match !== null) {
519+
const [, ref] = match;
520+
521+
// If the bad ref is trying to find a parent ref, assume we hit to the last commit, so try again using the root sha
522+
if (ref === ref1 && ref.endsWith('^')) {
523+
return Git.diff(repoPath, fileName, rootSha, ref2, options);
524+
}
525+
}
526+
527+
throw ex;
528+
}
496529
}
497530

498531
static diff_nameStatus(repoPath: string, ref1?: string, ref2?: string, options: { filter?: string } = {}) {

src/git/gitService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ export class GitService implements Disposable {
12051205
const [file, root] = Git.splitPath(fileName, repoPath, false);
12061206

12071207
try {
1208-
const data = await Git.diff(root, file, ref1, ref2, options);
1208+
const data = await Git.diff(root, file, ref1, ref2, { ...options, filter: 'M' });
12091209
const diff = GitDiffParser.parse(data);
12101210
return diff;
12111211
}

0 commit comments

Comments
 (0)