Skip to content

Commit 7bb48ae

Browse files
committed
Fixes stashed file diffs
1 parent a4115ff commit 7bb48ae

File tree

8 files changed

+63
-18
lines changed

8 files changed

+63
-18
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
66

77
## [Unreleased]
8+
### Fixed
9+
- Fixes issue where diffs for stashed files were often wrong (missing)
810

911
## [5.6.0] - 2017-10-11
1012
### Added

src/commands/diffLineWithWorking.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand {
4343
args.commit = blame.commit;
4444
// If the line is uncommitted, find the previous commit
4545
if (args.commit.isUncommitted) {
46-
args.commit = new GitCommit(args.commit.type, args.commit.repoPath, args.commit.previousSha!, args.commit.previousFileName!, args.commit.author, args.commit.date, args.commit.message);
46+
args.commit = args.commit.with({
47+
sha: args.commit.previousSha!,
48+
fileName: args.commit.previousFileName!,
49+
originalFileName: null,
50+
previousSha: null,
51+
previousFileName: null
52+
});
4753
args.line = blame.line.line + 1;
4854
}
4955
}

src/git/git.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ function gitCommandDefaultErrorHandler(ex: Error, options: GitCommandOptions, ..
9494

9595
export class Git {
9696

97-
static shaRegex = /^[0-9a-f]{40}( -)?$/;
98-
static uncommittedRegex = /^[0]+$/;
97+
static shaRegex = /^[0-9a-f]{40}(\^[0-9]*?)??( -)?$/;
98+
static uncommittedRegex = /^[0]{40}(\^[0-9]*?)??$/;
9999

100100
static gitInfo(): IGit {
101101
return git;
@@ -156,6 +156,9 @@ export class Git {
156156
}
157157

158158
static shortenSha(sha: string) {
159+
const index = sha.indexOf('^');
160+
// This is lame, but assume there is only 1 character after the ^
161+
if (index > 6) return `${sha.substring(0, 6)}${sha.substring(index)}`;
159162
return sha.substring(0, 8);
160163
}
161164

@@ -385,8 +388,6 @@ export class Git {
385388

386389
static async show(repoPath: string | undefined, fileName: string, branchOrSha: string, encoding?: string) {
387390
const [file, root] = Git.splitPath(fileName, repoPath);
388-
branchOrSha = branchOrSha.replace('^', '');
389-
390391
if (Git.isUncommitted(branchOrSha)) throw new Error(`sha=${branchOrSha} is uncommitted`);
391392

392393
const opts = { cwd: root, encoding: encoding || defaultEncoding, overrideErrorHandling: true };

src/git/models/commit.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,21 @@ export class GitCommit {
9898
return GitUri.getFormattedPath(this.fileName, separator);
9999
}
100100

101-
with(changes: { type?: GitCommitType, fileName?: string, sha?: string, originalFileName?: string, previousFileName?: string, previousSha?: string }) {
102-
return new GitCommit(changes.type || this.type, this.repoPath,
103-
changes.sha || this.sha, changes.fileName || this.fileName,
104-
this.author, this.date, this.message,
105-
changes.originalFileName || this.originalFileName,
106-
changes.previousSha || this.previousSha, changes.previousFileName || this.previousFileName);
101+
with(changes: { type?: GitCommitType, sha?: string, fileName?: string, originalFileName?: string | null, previousFileName?: string | null, previousSha?: string | null }): GitCommit {
102+
return new GitCommit(changes.type || this.type,
103+
this.repoPath,
104+
changes.sha || this.sha,
105+
changes.fileName || this.fileName,
106+
this.author,
107+
this.date,
108+
this.message,
109+
this.getChangedValue(changes.originalFileName, this.originalFileName),
110+
this.getChangedValue(changes.previousSha, this.previousSha),
111+
this.getChangedValue(changes.previousFileName, this.previousFileName));
112+
}
113+
114+
protected getChangedValue<T>(change: T | null | undefined, original: T | undefined): T | undefined {
115+
if (change === undefined) return original;
116+
return change !== null ? change : undefined;
107117
}
108118
}

src/git/models/logCommit.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,30 @@ export class GitLogCommit extends GitCommit {
6868
const changed = this.fileStatuses.filter(_ => _.status !== 'A' && _.status !== '?' && _.status !== 'D').length;
6969
return `+${added} ~${changed} -${deleted}`;
7070
}
71+
72+
toFileCommit(status: IGitStatusFile): GitLogCommit {
73+
return this.with({
74+
type: GitCommitType.File,
75+
fileName: status.fileName,
76+
originalFileName: status.originalFileName,
77+
previousFileName: status.originalFileName || status.fileName,
78+
status: status.status,
79+
fileStatuses: null
80+
});
81+
}
82+
83+
with(changes: { type?: GitCommitType, sha?: string, fileName?: string, originalFileName?: string | null, previousFileName?: string | null, previousSha?: string | null, status?: GitStatusFileStatus, fileStatuses?: IGitStatusFile[] | null }): GitLogCommit {
84+
return new GitLogCommit(changes.type || this.type,
85+
this.repoPath,
86+
changes.sha || this.sha,
87+
changes.fileName || this.fileName,
88+
this.author,
89+
this.date,
90+
this.message,
91+
changes.status || this.status,
92+
this.getChangedValue(changes.fileStatuses, this.fileStatuses),
93+
this.getChangedValue(changes.originalFileName, this.originalFileName),
94+
this.getChangedValue(changes.previousSha, this.previousSha),
95+
this.getChangedValue(changes.previousFileName, this.previousFileName));
96+
}
7197
}

src/git/parsers/stashParser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class GitStashParser {
2424

2525
let commit = commits.get(entry.sha);
2626
if (commit === undefined) {
27-
commit = new GitStashCommit(entry.stashName, repoPath, entry.sha, entry.fileNames, new Date(entry.date! as any * 1000), entry.summary, undefined, entry.fileStatuses) as GitStashCommit;
27+
commit = new GitStashCommit(entry.stashName, repoPath, entry.sha, entry.fileNames, new Date(entry.date! as any * 1000), entry.summary, undefined, entry.fileStatuses, undefined, `${entry.sha}^1`) as GitStashCommit;
2828
commits.set(entry.sha, commit);
2929
}
3030
}

src/views/stashFileNode.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
'use strict';
22
import { ExtensionContext } from 'vscode';
33
import { ResourceType } from './explorerNode';
4-
import { GitService, GitStashCommit, IGitStatusFile } from '../gitService';
4+
import { GitLogCommit, GitService, IGitStatusFile } from '../gitService';
55
import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode';
66

77
export class StashFileNode extends CommitFileNode {
88

99
readonly resourceType: ResourceType = 'gitlens:stash-file';
1010

1111
constructor(
12-
readonly status: IGitStatusFile,
13-
readonly commit: GitStashCommit,
14-
readonly context: ExtensionContext,
15-
readonly git: GitService
12+
status: IGitStatusFile,
13+
commit: GitLogCommit,
14+
context: ExtensionContext,
15+
git: GitService
1616
) {
1717
super(status, commit, context, git, CommitFileNodeDisplayAs.File);
1818
}

src/views/stashNode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class StashNode extends ExplorerNode {
3131
}
3232
}
3333

34-
const children = statuses.map(s => new StashFileNode(s, this.commit, this.context, this.git));
34+
const children = statuses.map(s => new StashFileNode(s, this.commit.toFileCommit(s), this.context, this.git));
3535
children.sort((a, b) => a.label!.localeCompare(b.label!));
3636
return children;
3737
}

0 commit comments

Comments
 (0)