Skip to content

Commit 772fe27

Browse files
committed
Fixes #756, #809 - use ^ to ensure prev in diffs
1 parent 18d683b commit 772fe27

File tree

5 files changed

+50
-29
lines changed

5 files changed

+50
-29
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
88

99
### Fixed
1010

11+
- Fixes [#756](https://github.com/eamodio/vscode-gitlens/issues/756) - Merge commit shows only the changes from the last commit on those files
12+
- Fixes [#809](https://github.com/eamodio/vscode-gitlens/issues/809) - Wrong commit diff in file history
1113
- Fixes [#685](https://github.com/eamodio/vscode-gitlens/issues/685) - GitLens not loading for a single repository
1214
- Fixes [#789](https://github.com/eamodio/vscode-gitlens/issues/789) - Line blame annotations not working when vscode root is home dir and .gnupg dir is inaccessible
1315
- Fixes [#649](https://github.com/eamodio/vscode-gitlens/issues/649) - GitLens can't see the remote but git can

src/commands/diffWithPrevious.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22
import { commands, TextDocumentShowOptions, TextEditor, Uri } from 'vscode';
33
import { Container } from '../container';
4-
import { GitCommit, GitLogCommit, GitService, GitUri } from '../git/gitService';
4+
import { GitCommit, GitService, GitUri } from '../git/gitService';
55
import { Logger } from '../logger';
66
import { Messages } from '../messages';
77
import { ActiveEditorCommand, command, CommandContext, Commands, getCommandUri, openEditor } from './common';
@@ -50,16 +50,31 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
5050
args.line = editor == null ? 0 : editor.selection.active.line;
5151
}
5252

53-
const gitUri = args.commit !== undefined ? GitUri.fromCommit(args.commit) : await GitUri.fromUri(uri);
53+
if (args.commit !== undefined) {
54+
const diffArgs: DiffWithCommandArgs = {
55+
repoPath: args.commit.repoPath,
56+
lhs: {
57+
sha: `${args.commit.sha}^`,
58+
uri: args.commit.originalUri
59+
},
60+
rhs: {
61+
sha: args.commit.sha || '',
62+
uri: args.commit.uri
63+
},
64+
line: args.line,
65+
showOptions: args.showOptions
66+
};
67+
return commands.executeCommand(Commands.DiffWith, diffArgs);
68+
}
69+
70+
const gitUri = await GitUri.fromUri(uri);
5471
try {
5572
const diffUris = await Container.git.getPreviousDiffUris(
5673
gitUri.repoPath!,
5774
gitUri,
5875
gitUri.sha,
5976
// If we are in a diff editor, assume we are on the right side, and need to skip back 1 more revisions
60-
args.inDiffEditor ? 1 : 0,
61-
// If this is a merge commit, walk back using the first parent only
62-
args.commit && (args.commit as GitLogCommit).isMerge
77+
args.inDiffEditor ? 1 : 0
6378
);
6479

6580
if (diffUris === undefined || diffUris.previous === undefined) {

src/git/git.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -755,17 +755,20 @@ export class Git {
755755
static async log__file_recent(
756756
repoPath: string,
757757
fileName: string,
758-
{ similarityThreshold }: { similarityThreshold?: number } = {}
758+
{ ref, similarityThreshold }: { ref?: string; similarityThreshold?: number } = {}
759759
) {
760-
const data = await git<string>(
761-
{ cwd: repoPath, errors: GitErrorHandling.Ignore },
760+
const params = [
762761
'log',
763762
`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`,
764763
'-n1',
765-
'--format=%H',
766-
'--',
767-
fileName
768-
);
764+
'--format=%H'
765+
];
766+
767+
if (ref) {
768+
params.push(ref);
769+
}
770+
771+
const data = await git<string>({ cwd: repoPath, errors: GitErrorHandling.Ignore }, ...params, '--', fileName);
769772
return data.length === 0 ? undefined : data.trim();
770773
}
771774

src/git/gitService.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,13 +1072,13 @@ export class GitService implements Disposable {
10721072
) {
10731073
const [branches, tags] = await Promise.all<GitBranch[] | undefined, GitTag[] | undefined>([
10741074
include === 'all' || include === 'branches'
1075-
? Container.git.getBranches(repoPath, {
1075+
? this.getBranches(repoPath, {
10761076
...options,
10771077
filter: filterBranches && filterBranches
10781078
})
10791079
: undefined,
10801080
include === 'all' || include === 'tags'
1081-
? Container.git.getTags(repoPath, {
1081+
? this.getTags(repoPath, {
10821082
...options,
10831083
filter: filterTags && filterTags
10841084
})
@@ -1099,8 +1099,8 @@ export class GitService implements Disposable {
10991099
@log()
11001100
async getBranchesAndTagsTipsFn(repoPath: string | undefined, currentName?: string) {
11011101
const [branches, tags] = await Promise.all([
1102-
Container.git.getBranches(repoPath),
1103-
Container.git.getTags(repoPath, { includeRefs: true })
1102+
this.getBranches(repoPath),
1103+
this.getTags(repoPath, { includeRefs: true })
11041104
]);
11051105

11061106
const branchesAndTagsBySha = Arrays.groupByFilterMap(
@@ -1757,7 +1757,7 @@ export class GitService implements Disposable {
17571757

17581758
const next = await this.getNextUri(repoPath, uri, ref);
17591759
if (next === undefined) {
1760-
const status = await Container.git.getStatusForFile(repoPath, fileName);
1760+
const status = await this.getStatusForFile(repoPath, fileName);
17611761
if (status !== undefined) {
17621762
// If the file is staged, diff with the staged version
17631763
if (status.indexStatus !== undefined) {
@@ -1847,7 +1847,7 @@ export class GitService implements Disposable {
18471847
// If we are at the working tree (i.e. no ref), we need to dig deeper to figure out where to go
18481848
if (ref === undefined || ref.length === 0) {
18491849
// First, check the file status to see if there is anything staged
1850-
const status = await Container.git.getStatusForFile(repoPath, fileName);
1850+
const status = await this.getStatusForFile(repoPath, fileName);
18511851
if (status !== undefined) {
18521852
// If the file is staged with working changes, diff working with staged (index)
18531853
// If the file is staged without working changes, diff staged with HEAD
@@ -1939,7 +1939,7 @@ export class GitService implements Disposable {
19391939
// If the document is dirty (unsaved), use the status to determine where to go
19401940
if (document.isDirty) {
19411941
// Check the file status to see if there is anything staged
1942-
const status = await Container.git.getStatusForFile(repoPath, fileName);
1942+
const status = await this.getStatusForFile(repoPath, fileName);
19431943
if (status !== undefined) {
19441944
// If the file is staged, diff working with staged (index)
19451945
// If the file is not staged, diff working with HEAD
@@ -2057,7 +2057,7 @@ export class GitService implements Disposable {
20572057
GitErrors.invalidLineCount.test(ex.message)
20582058
) {
20592059
if (ref === undefined) {
2060-
const status = await Container.git.getStatusForFile(repoPath, fileName);
2060+
const status = await this.getStatusForFile(repoPath, fileName);
20612061
if (status !== undefined && status.indexStatus !== undefined) {
20622062
return GitUri.fromFile(fileName, repoPath, GitService.uncommittedStagedSha);
20632063
}
@@ -2663,19 +2663,15 @@ export class GitService implements Disposable {
26632663
return (await Git.rev_parse(repoPath, ref)) || ref;
26642664
}
26652665

2666+
const fileName = Strings.normalizePath(paths.relative(repoPath, uri.fsPath));
2667+
26662668
const match = Git.shaParentRegex.exec(ref);
26672669
if (match != null) {
2668-
const previousUri = await Container.git.getPreviousUri(repoPath, uri, match[1]);
2669-
if (previousUri !== undefined && previousUri.sha !== undefined) {
2670-
return previousUri.sha;
2671-
}
2670+
const parentRef = await Git.log__file_recent(repoPath, fileName, { ref: ref });
2671+
if (parentRef !== undefined) return parentRef;
26722672
}
26732673

2674-
const ensuredRef = await Git.cat_file__resolve(
2675-
repoPath,
2676-
Strings.normalizePath(paths.relative(repoPath, uri.fsPath)),
2677-
ref
2678-
);
2674+
const ensuredRef = await Git.cat_file__resolve(repoPath, fileName, ref);
26792675
if (ensuredRef === undefined) return ref;
26802676

26812677
return ensuredRef;

src/git/models/commit.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ export abstract class GitCommit {
115115
return Git.isUncommittedStaged(this.sha);
116116
}
117117

118+
@memoize()
119+
get originalUri(): Uri {
120+
return this.originalFileName ? GitUri.resolveToUri(this.originalFileName, this.repoPath) : this.uri;
121+
}
122+
118123
get previousFileSha(): string {
119124
return `${this.sha}^`;
120125
}

0 commit comments

Comments
 (0)