Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/git/src/quickDiffProvider.ts
13383 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { FileType, l10n, LogOutputChannel, QuickDiffProvider, Uri, workspace } from 'vscode';
7
import { IRepositoryResolver, Repository } from './repository';
8
import { isDescendant, pathEquals } from './util';
9
import { toGitUri } from './uri';
10
import { Status } from './api/git.constants';
11
12
export class GitQuickDiffProvider implements QuickDiffProvider {
13
readonly label = l10n.t('Git Local Changes (Working Tree)');
14
15
constructor(
16
private readonly repository: Repository,
17
private readonly repositoryResolver: IRepositoryResolver,
18
private readonly logger: LogOutputChannel
19
) { }
20
21
async provideOriginalResource(uri: Uri): Promise<Uri | undefined> {
22
this.logger.trace(`[Repository][provideOriginalResource] Resource: ${uri.toString()}`);
23
24
if (uri.scheme !== 'file') {
25
this.logger.trace(`[Repository][provideOriginalResource] Resource is not a file: ${uri.scheme}`);
26
return undefined;
27
}
28
29
// Ignore path that is inside the .git directory (ex: COMMIT_EDITMSG)
30
if (isDescendant(this.repository.dotGit.commonPath ?? this.repository.dotGit.path, uri.fsPath)) {
31
this.logger.trace(`[Repository][provideOriginalResource] Resource is inside .git directory: ${uri.toString()}`);
32
return undefined;
33
}
34
35
// Ignore symbolic links
36
const stat = await workspace.fs.stat(uri);
37
if ((stat.type & FileType.SymbolicLink) !== 0) {
38
this.logger.trace(`[Repository][provideOriginalResource] Resource is a symbolic link: ${uri.toString()}`);
39
return undefined;
40
}
41
42
// Ignore path that is not inside the current repository
43
if (this.repositoryResolver.getRepository(uri) !== this.repository) {
44
this.logger.trace(`[Repository][provideOriginalResource] Resource is not part of the repository: ${uri.toString()}`);
45
return undefined;
46
}
47
48
// Ignore path that is inside a hidden repository
49
if (this.repository.isHidden === true) {
50
this.logger.trace(`[Repository][provideOriginalResource] Repository is hidden: ${uri.toString()}`);
51
return undefined;
52
}
53
54
// Ignore path that is inside a merge group
55
if (this.repository.mergeGroup.resourceStates.some(r => pathEquals(r.resourceUri.fsPath, uri.fsPath))) {
56
this.logger.trace(`[Repository][provideOriginalResource] Resource is part of a merge group: ${uri.toString()}`);
57
return undefined;
58
}
59
60
// Ignore path that is untracked
61
if (this.repository.untrackedGroup.resourceStates.some(r => pathEquals(r.resourceUri.path, uri.path)) ||
62
this.repository.workingTreeGroup.resourceStates.some(r => pathEquals(r.resourceUri.path, uri.path) && r.type === Status.UNTRACKED)) {
63
this.logger.trace(`[Repository][provideOriginalResource] Resource is untracked: ${uri.toString()}`);
64
return undefined;
65
}
66
67
// Ignore path that is git ignored
68
const ignored = await this.repository.checkIgnore([uri.fsPath]);
69
if (ignored.size > 0) {
70
this.logger.trace(`[Repository][provideOriginalResource] Resource is git ignored: ${uri.toString()}`);
71
return undefined;
72
}
73
74
const originalResource = toGitUri(uri, '', { replaceFileExtension: true });
75
this.logger.trace(`[Repository][provideOriginalResource] Original resource: ${originalResource.toString()}`);
76
77
return originalResource;
78
}
79
}
80
81
export class StagedResourceQuickDiffProvider implements QuickDiffProvider {
82
readonly label = l10n.t('Git Local Changes (Index)');
83
84
constructor(
85
private readonly _repository: Repository,
86
private readonly logger: LogOutputChannel
87
) { }
88
89
async provideOriginalResource(uri: Uri): Promise<Uri | undefined> {
90
this.logger.trace(`[StagedResourceQuickDiffProvider][provideOriginalResource] Resource: ${uri.toString()}`);
91
92
if (uri.scheme !== 'file') {
93
this.logger.trace(`[StagedResourceQuickDiffProvider][provideOriginalResource] Resource is not a file: ${uri.scheme}`);
94
return undefined;
95
}
96
97
// Ignore path that is inside a hidden repository
98
if (this._repository.isHidden === true) {
99
this.logger.trace(`[StagedResourceQuickDiffProvider][provideOriginalResource] Repository is hidden: ${uri.toString()}`);
100
return undefined;
101
}
102
103
// Ignore symbolic links
104
const stat = await workspace.fs.stat(uri);
105
if ((stat.type & FileType.SymbolicLink) !== 0) {
106
this.logger.trace(`[StagedResourceQuickDiffProvider][provideOriginalResource] Resource is a symbolic link: ${uri.toString()}`);
107
return undefined;
108
}
109
110
// Ignore resources that are not in the index group
111
if (!this._repository.indexGroup.resourceStates.some(r => pathEquals(r.resourceUri.fsPath, uri.fsPath))) {
112
this.logger.trace(`[StagedResourceQuickDiffProvider][provideOriginalResource] Resource is not part of a index group: ${uri.toString()}`);
113
return undefined;
114
}
115
116
const originalResource = toGitUri(uri, 'HEAD', { replaceFileExtension: true });
117
this.logger.trace(`[StagedResourceQuickDiffProvider][provideOriginalResource] Original resource: ${originalResource.toString()}`);
118
return originalResource;
119
}
120
}
121
122