소스 검색

Adds caching to stashes & contributors

main
Eric Amodio 3 년 전
부모
커밋
e7ddef7df2
9개의 변경된 파일102개의 추가작업 그리고 30개의 파일을 삭제
  1. +4
    -0
      CHANGELOG.md
  2. +61
    -28
      src/git/gitService.ts
  3. +7
    -0
      src/views/branchesView.ts
  4. +7
    -0
      src/views/contributorsView.ts
  5. +1
    -1
      src/views/nodes/remotesNode.ts
  6. +1
    -1
      src/views/nodes/stashesNode.ts
  7. +7
    -0
      src/views/remotesView.ts
  8. +7
    -0
      src/views/stashesView.ts
  9. +7
    -0
      src/views/tagsView.ts

+ 4
- 0
CHANGELOG.md 파일 보기

@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
## [Unreleased]
### Changes
- Improves the performance of the _Stashes_ and _Contributors_ views
### Fixed
- Fixes [#1294](https://github.com/eamodio/vscode-gitlens/issues/1294) - Error when open commits list

+ 61
- 28
src/git/gitService.ts 파일 보기

@ -129,7 +129,9 @@ export class GitService implements Disposable {
private _repositoriesLoadingPromise: Promise<void> | undefined;
private readonly _branchesCache = new Map<string, GitBranch[]>();
private readonly _contributorsCache = new Map<string, GitContributor[]>();
private readonly _remotesWithApiProviderCache = new Map<string, GitRemote<RichRemoteProvider> | null>();
private readonly _stashesCache = new Map<string, GitStash | null>();
private readonly _tagsCache = new Map<string, GitTag[]>();
private readonly _trackedCache = new Map<string, boolean | Promise<boolean>>();
private readonly _userMapCache = new Map<string, { name?: string; email?: string } | null>();
@ -157,7 +159,9 @@ export class GitService implements Disposable {
dispose() {
this._repositoryTree.forEach(r => r.dispose());
this._branchesCache.clear();
this._contributorsCache.clear();
this._remotesWithApiProviderCache.clear();
this._stashesCache.clear();
this._tagsCache.clear();
this._trackedCache.clear();
this._userMapCache.clear();
@ -186,12 +190,20 @@ export class GitService implements Disposable {
}
private onAnyRepositoryChanged(repo: Repository, e: RepositoryChangeEvent) {
if (e.changed(RepositoryChange.Stash, true)) return;
if (e.changed(RepositoryChange.Stash, true)) {
this._stashesCache.delete(repo.path);
return;
}
this._branchesCache.delete(repo.path);
this._contributorsCache.delete(repo.path);
if (e.changed(RepositoryChange.Remotes)) {
this._remotesWithApiProviderCache.clear();
}
if (e.changed(RepositoryChange.Stash)) {
this._stashesCache.delete(repo.path);
}
this._tagsCache.delete(repo.path);
this._trackedCache.clear();
@ -1393,31 +1405,43 @@ export class GitService implements Disposable {
async getContributors(repoPath: string): Promise<GitContributor[]> {
if (repoPath == null) return [];
try {
const data = await Git.shortlog(repoPath);
const shortlog = GitShortLogParser.parse(data, repoPath);
if (shortlog == null) return [];
// Mark the current user
const currentUser = await Container.git.getCurrentUser(repoPath);
if (currentUser != null) {
const index = shortlog.contributors.findIndex(
c => currentUser.email === c.email && currentUser.name === c.name,
);
if (index !== -1) {
const c = shortlog.contributors[index];
shortlog.contributors.splice(
index,
1,
new GitContributor(c.repoPath, c.name, c.email, c.count, true),
);
let contributors = this.useCaching ? this._contributorsCache.get(repoPath) : undefined;
if (contributors == null) {
try {
const data = await Git.shortlog(repoPath);
const shortlog = GitShortLogParser.parse(data, repoPath);
if (shortlog != null) {
// Mark the current user
const currentUser = await Container.git.getCurrentUser(repoPath);
if (currentUser != null) {
const index = shortlog.contributors.findIndex(
c => currentUser.email === c.email && currentUser.name === c.name,
);
if (index !== -1) {
const c = shortlog.contributors[index];
shortlog.contributors.splice(
index,
1,
new GitContributor(c.repoPath, c.name, c.email, c.count, true),
);
}
}
contributors = shortlog.contributors;
} else {
contributors = [];
}
}
return shortlog.contributors;
} catch (ex) {
return [];
const repo = await this.getRepository(repoPath);
if (repo?.supportsChangeEvents) {
this._contributorsCache.set(repoPath, contributors);
}
} catch (ex) {
return [];
}
}
return contributors;
}
@log()
@ -3236,11 +3260,20 @@ export class GitService implements Disposable {
async getStash(repoPath: string | undefined): Promise<GitStash | undefined> {
if (repoPath == null) return undefined;
const data = await Git.stash__list(repoPath, {
similarityThreshold: Container.config.advanced.similarityThreshold,
});
const stash = GitStashParser.parse(data, repoPath);
return stash;
let stash = this.useCaching ? this._stashesCache.get(repoPath) : undefined;
if (stash === undefined) {
const data = await Git.stash__list(repoPath, {
similarityThreshold: Container.config.advanced.similarityThreshold,
});
stash = GitStashParser.parse(data, repoPath);
const repo = await this.getRepository(repoPath);
if (repo?.supportsChangeEvents) {
this._stashesCache.set(repoPath, stash ?? null);
}
}
return stash ?? undefined;
}
@log()

+ 7
- 0
src/views/branchesView.ts 파일 보기

@ -85,6 +85,13 @@ export class BranchesViewNode extends ViewNode {
const [child] = this.children;
const branches = await child.repo.getBranches({ filter: b => !b.remote });
if (branches.length === 0) {
this.view.message = 'No branches could be found.';
return [];
}
this.view.message = undefined;
this.view.title = `Branches (${branches.length})`;
return child.getChildren();

+ 7
- 0
src/views/contributorsView.ts 파일 보기

@ -65,6 +65,13 @@ export class ContributorsViewNode extends ViewNode {
const [child] = this.children;
const contributors = await child.repo.getContributors();
if (contributors.length === 0) {
this.view.message = 'No contributors could be found.';
return [];
}
this.view.message = undefined;
this.view.title = `Contributors (${contributors.length})`;
return child.getChildren();

+ 1
- 1
src/views/nodes/remotesNode.ts 파일 보기

@ -33,7 +33,7 @@ export class RemotesNode extends ViewNode {
async getChildren(): Promise<ViewNode[]> {
if (this._children == null) {
const remotes = await this.repo.getRemotes({ sort: true });
if (remotes == null || remotes.length === 0) {
if (remotes.length === 0) {
return [new MessageNode(this.view, this, 'No remotes could be found')];
}

+ 1
- 1
src/views/nodes/stashesNode.ts 파일 보기

@ -30,7 +30,7 @@ export class StashesNode extends ViewNode {
async getChildren(): Promise<ViewNode[]> {
if (this._children == null) {
const stash = await this.repo.getStash();
if (stash === undefined) return [new MessageNode(this.view, this, 'No stashes could be found.')];
if (stash == null) return [new MessageNode(this.view, this, 'No stashes could be found.')];
this._children = [...Iterables.map(stash.commits.values(), c => new StashNode(this.view, this, c))];
}

+ 7
- 0
src/views/remotesView.ts 파일 보기

@ -81,6 +81,13 @@ export class RemotesViewNode extends ViewNode {
const [child] = this.children;
const remotes = await child.repo.getRemotes();
if (remotes.length === 0) {
this.view.message = 'No remotes could be found.';
return [];
}
this.view.message = undefined;
this.view.title = `Remotes (${remotes.length})`;
return child.getChildren();

+ 7
- 0
src/views/stashesView.ts 파일 보기

@ -63,6 +63,13 @@ export class StashesViewNode extends ViewNode {
const [child] = this.children;
const stash = await child.repo.getStash();
if (stash == null) {
this.view.message = 'No stashes could be found.';
return [];
}
this.view.message = undefined;
this.view.title = `Stashes (${stash?.commits.size ?? 0})`;
return child.getChildren();

+ 7
- 0
src/views/tagsView.ts 파일 보기

@ -64,6 +64,13 @@ export class TagsViewNode extends ViewNode {
const [child] = this.children;
const tags = await child.repo.getTags();
if (tags.length === 0) {
this.view.message = 'No tags could be found.';
return [];
}
this.view.message = undefined;
this.view.title = `Tags (${tags.length})`;
return child.getChildren();

불러오는 중...
취소
저장