Skip to content

Commit 05b287c

Browse files
committed
Refactors Git provider into sub-providers
- Contributor operations
1 parent 9bfae95 commit 05b287c

File tree

12 files changed

+318
-278
lines changed

12 files changed

+318
-278
lines changed

src/commands/quickCommand.steps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1371,7 +1371,7 @@ export function* pickContributorsStep<
13711371

13721372
const items = [];
13731373

1374-
for (const c of await state.repo.git.getContributors()) {
1374+
for (const c of await state.repo.git.contributors().getContributors()) {
13751375
items.push(
13761376
await createContributorQuickPickItem(c, message?.includes(c.getCoauthor()), {
13771377
buttons: [RevealInSideBarQuickInputButton],

src/env/node/git/localGitProvider.ts

Lines changed: 6 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ import {
5454
getRemoteNameFromBranchName,
5555
} from '../../../git/models/branch.utils';
5656
import type { GitCommit, GitStashCommit } from '../../../git/models/commit';
57-
import type { GitContributorStats } from '../../../git/models/contributor';
58-
import { GitContributor } from '../../../git/models/contributor';
59-
import { calculateContributionScore } from '../../../git/models/contributor.utils';
6057
import type {
6158
GitDiff,
6259
GitDiffFile,
@@ -114,7 +111,6 @@ import {
114111
import {
115112
createLogParserSingle,
116113
createLogParserWithFilesAndStats,
117-
getContributorsParser,
118114
getGraphParser,
119115
getGraphStatsParser,
120116
getRefAndDateParser,
@@ -182,6 +178,7 @@ import type { GitLocation } from './locator';
182178
import { findGitPath, InvalidGitConfigError, UnableToFindGitError } from './locator';
183179
import { CancelledRunError, fsExists } from './shell';
184180
import { BranchesGitSubProvider } from './sub-providers/branches';
181+
import { ContributorsGitSubProvider } from './sub-providers/contributors';
185182
import { PatchGitSubProvider } from './sub-providers/patch';
186183
import { RemotesGitSubProvider } from './sub-providers/remotes';
187184
import { StagingGitSubProvider } from './sub-providers/staging';
@@ -2454,162 +2451,6 @@ export class LocalGitProvider implements GitProvider, Disposable {
24542451
return this.git.config__set(key, value, repoPath);
24552452
}
24562453

2457-
@log()
2458-
async getContributorsStats(
2459-
repoPath: string,
2460-
options?: { merges?: boolean; since?: string },
2461-
): Promise<GitContributorStats | undefined> {
2462-
if (repoPath == null) return undefined;
2463-
2464-
const scope = getLogScope();
2465-
2466-
const args = ['shortlog', '-s', '--all'];
2467-
if (!options?.merges) {
2468-
args.push('--no-merges');
2469-
}
2470-
if (options?.since) {
2471-
args.push(`--since=${options.since}`);
2472-
}
2473-
2474-
try {
2475-
const data = await this.git.exec<string>({ cwd: repoPath }, ...args);
2476-
if (data == null) return undefined;
2477-
2478-
const contributions = data
2479-
.split('\n')
2480-
.map(line => parseInt(line.trim().split('\t', 1)[0], 10))
2481-
.filter(c => !isNaN(c))
2482-
.sort((a, b) => b - a);
2483-
2484-
const result: GitContributorStats = {
2485-
count: contributions.length,
2486-
contributions: contributions,
2487-
};
2488-
return result;
2489-
} catch (ex) {
2490-
Logger.error(ex, scope);
2491-
debugger;
2492-
2493-
return undefined;
2494-
}
2495-
}
2496-
2497-
@log()
2498-
async getContributors(
2499-
repoPath: string,
2500-
options?: { all?: boolean; merges?: boolean | 'first-parent'; ref?: string; stats?: boolean },
2501-
): Promise<GitContributor[]> {
2502-
if (repoPath == null) return [];
2503-
2504-
let key = options?.ref ?? '';
2505-
if (options?.all) {
2506-
key += ':all';
2507-
}
2508-
if (options?.merges) {
2509-
key += `:merges:${options.merges}`;
2510-
}
2511-
if (options?.stats) {
2512-
key += ':stats';
2513-
}
2514-
2515-
const contributorsCache = this._cache.contributors?.get(repoPath);
2516-
2517-
let contributors = contributorsCache?.get(key);
2518-
if (contributors == null) {
2519-
async function load(this: LocalGitProvider) {
2520-
try {
2521-
repoPath = normalizePath(repoPath);
2522-
const currentUser = await this.getCurrentUser(repoPath);
2523-
const parser = getContributorsParser(options?.stats);
2524-
2525-
const args = [...parser.arguments, '--full-history', '--use-mailmap'];
2526-
2527-
const merges = options?.merges ?? true;
2528-
if (merges) {
2529-
args.push(merges === 'first-parent' ? '--first-parent' : '--no-min-parents');
2530-
} else {
2531-
args.push('--no-merges');
2532-
}
2533-
2534-
if (options?.all) {
2535-
args.push('--all', '--single-worktree');
2536-
}
2537-
2538-
const data = await this.git.log(repoPath, { ref: options?.ref }, ...args);
2539-
2540-
const contributors = new Map<string, GitContributor>();
2541-
const commits = parser.parse(data);
2542-
for (const c of commits) {
2543-
const key = `${c.author}|${c.email}`;
2544-
const timestamp = Number(c.date) * 1000;
2545-
2546-
let contributor: Mutable<GitContributor> | undefined = contributors.get(key);
2547-
if (contributor == null) {
2548-
contributor = new GitContributor(
2549-
repoPath,
2550-
c.author,
2551-
c.email,
2552-
1,
2553-
new Date(timestamp),
2554-
new Date(timestamp),
2555-
isUserMatch(currentUser, c.author, c.email),
2556-
c.stats
2557-
? {
2558-
...c.stats,
2559-
contributionScore: calculateContributionScore(c.stats, timestamp),
2560-
}
2561-
: undefined,
2562-
);
2563-
contributors.set(key, contributor);
2564-
} else {
2565-
contributor.commits++;
2566-
const date = new Date(timestamp);
2567-
if (date > contributor.latestCommitDate!) {
2568-
contributor.latestCommitDate = date;
2569-
}
2570-
if (date < contributor.firstCommitDate!) {
2571-
contributor.firstCommitDate = date;
2572-
}
2573-
if (options?.stats && c.stats != null) {
2574-
if (contributor.stats == null) {
2575-
contributor.stats = {
2576-
...c.stats,
2577-
contributionScore: calculateContributionScore(c.stats, timestamp),
2578-
};
2579-
} else {
2580-
contributor.stats = {
2581-
additions: contributor.stats.additions + c.stats.additions,
2582-
deletions: contributor.stats.deletions + c.stats.deletions,
2583-
files: contributor.stats.files + c.stats.files,
2584-
contributionScore:
2585-
contributor.stats.contributionScore +
2586-
calculateContributionScore(c.stats, timestamp),
2587-
};
2588-
}
2589-
}
2590-
}
2591-
}
2592-
2593-
return [...contributors.values()];
2594-
} catch (_ex) {
2595-
contributorsCache?.delete(key);
2596-
2597-
return [];
2598-
}
2599-
}
2600-
2601-
contributors = load.call(this);
2602-
2603-
if (contributorsCache == null) {
2604-
this._cache.contributors?.set(repoPath, new Map([[key, contributors]]));
2605-
} else {
2606-
contributorsCache.set(key, contributors);
2607-
}
2608-
}
2609-
2610-
return contributors;
2611-
}
2612-
26132454
@gate()
26142455
@log()
26152456
async getCurrentUser(repoPath: string): Promise<GitUser | undefined> {
@@ -4833,6 +4674,11 @@ export class LocalGitProvider implements GitProvider, Disposable {
48334674
return (this._branches ??= new BranchesGitSubProvider(this.container, this.git, this._cache, this));
48344675
}
48354676

4677+
private _contributors: ContributorsGitSubProvider | undefined;
4678+
get contributors(): ContributorsGitSubProvider {
4679+
return (this._contributors ??= new ContributorsGitSubProvider(this.container, this.git, this._cache, this));
4680+
}
4681+
48364682
private _patch: PatchGitSubProvider | undefined;
48374683
get patch(): PatchGitSubProvider | undefined {
48384684
return (this._patch ??= new PatchGitSubProvider(this.container, this.git, this));

src/env/node/git/operations/branches.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
181181
const mergeBase = await this.getMergeBase(repoPath, ref, baseOrTargetBranch);
182182
if (mergeBase == null) return undefined;
183183

184-
const contributors = await this.provider.getContributors(repoPath, {
184+
const contributors = await this.provider.contributors.getContributors(repoPath, {
185185
ref: createRevisionRange(mergeBase, ref, '..'),
186186
stats: true,
187187
});

src/env/node/git/sub-providers/branches.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
181181
const mergeBase = await this.getMergeBase(repoPath, ref, baseOrTargetBranch);
182182
if (mergeBase == null) return undefined;
183183

184-
const contributors = await this.provider.getContributors(repoPath, {
184+
const contributors = await this.provider.contributors.getContributors(repoPath, {
185185
ref: createRevisionRange(mergeBase, ref, '..'),
186186
stats: true,
187187
});

0 commit comments

Comments
 (0)