@@ -54,9 +54,6 @@ import {
54
54
getRemoteNameFromBranchName ,
55
55
} from '../../../git/models/branch.utils' ;
56
56
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' ;
60
57
import type {
61
58
GitDiff ,
62
59
GitDiffFile ,
@@ -114,7 +111,6 @@ import {
114
111
import {
115
112
createLogParserSingle ,
116
113
createLogParserWithFilesAndStats ,
117
- getContributorsParser ,
118
114
getGraphParser ,
119
115
getGraphStatsParser ,
120
116
getRefAndDateParser ,
@@ -182,6 +178,7 @@ import type { GitLocation } from './locator';
182
178
import { findGitPath , InvalidGitConfigError , UnableToFindGitError } from './locator' ;
183
179
import { CancelledRunError , fsExists } from './shell' ;
184
180
import { BranchesGitSubProvider } from './sub-providers/branches' ;
181
+ import { ContributorsGitSubProvider } from './sub-providers/contributors' ;
185
182
import { PatchGitSubProvider } from './sub-providers/patch' ;
186
183
import { RemotesGitSubProvider } from './sub-providers/remotes' ;
187
184
import { StagingGitSubProvider } from './sub-providers/staging' ;
@@ -2454,162 +2451,6 @@ export class LocalGitProvider implements GitProvider, Disposable {
2454
2451
return this . git . config__set ( key , value , repoPath ) ;
2455
2452
}
2456
2453
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
-
2613
2454
@gate ( )
2614
2455
@log ( )
2615
2456
async getCurrentUser ( repoPath : string ) : Promise < GitUser | undefined > {
@@ -4833,6 +4674,11 @@ export class LocalGitProvider implements GitProvider, Disposable {
4833
4674
return ( this . _branches ??= new BranchesGitSubProvider ( this . container , this . git , this . _cache , this ) ) ;
4834
4675
}
4835
4676
4677
+ private _contributors : ContributorsGitSubProvider | undefined ;
4678
+ get contributors ( ) : ContributorsGitSubProvider {
4679
+ return ( this . _contributors ??= new ContributorsGitSubProvider ( this . container , this . git , this . _cache , this ) ) ;
4680
+ }
4681
+
4836
4682
private _patch : PatchGitSubProvider | undefined ;
4837
4683
get patch ( ) : PatchGitSubProvider | undefined {
4838
4684
return ( this . _patch ??= new PatchGitSubProvider ( this . container , this . git , this ) ) ;
0 commit comments