gitwho is a PowerShell 7 module for explainable, folder-level code ownership recommendations derived from Git history.
The current foundation analyses real Git repositories, honours .mailmap, aggregates contributor activity into directory/month buckets, persists a versioned JSON cache, ranks contributors with visible scoring evidence and confidence reasons, and generates an interactive D3 ownership report. Advanced identity and configuration commands remain planned work.
- PowerShell 7 or newer
- Git available on
PATH - Pester 5 or newer for tests
Import-Module ./CodeOwnership/CodeOwnership.psd1 -ForceInvoke-CodeOwnershipAnalysis `
-RepositoryPath . `
-Bucket Month `
-OutputPath .codeownership/analysis.json `
-PassThruThe cache has schemaVersion = 1 and contains repository metadata, canonical contributors, raw identity aliases, case-preserving directory nodes, aggregated activity, and diagnostics. Git's repository-relative / separators are retained; literal backslashes in Unix filenames are not rewritten.
Git history is read with null-delimited, machine-readable git log --numstat -z output. Merge commits are ignored, .mailmap canonical names and emails are used for aggregation, and raw identities remain available as alias evidence. Binary changes contribute zero line churn and are counted in diagnostics. Renames are attributed to the destination path and counted separately. Cached results are reused only when the repository root, HEAD, bucket, and effective mailmap inputs are unchanged.
Get-CodeOwnerSuggestion `
-AnalysisPath .codeownership/analysis.json `
-Path src/Payments `
-Profile Balanced `
-From 2025-01-01 `
-To 2025-12-31 `
-Top 3The Balanced profile uses these weights when current surviving-line blame data is unavailable:
| Factor | Weight |
|---|---|
| Recency-weighted churn | 3/7 |
| Recency-weighted commit touches | 2/7 |
| File breadth | 2/7 |
Weights are calculated by removing the unavailable blame factor and normalising the remainder; they are not separately hard-coded. Recency uses exponential half-life decay and the selected range end as its reference date. File identities retained in each activity bucket let file breadth remain distinct across multi-period ranges. Each suggestion returns raw metrics, normalised factor shares, factor weights and contributions, the final score, and confidence evidence.
Date bounds use bucket-overlap semantics: a monthly, weekly, or quarterly bucket is included when any part of that bucket overlaps the requested range. This makes partial-month -From and -To values symmetric while preserving the cache's aggregate granularity.
New-CodeOwnershipReport `
-AnalysisPath .codeownership/analysis.json `
-OutputPath .codeownership/ownership-report.html `
-AssetMode Embedded `
-EmailDisplay HiddenThe default embedded report is a single offline HTML file containing the analysis, styles, application code, and vendored D3 runtime. It provides folder and date-range filters, selectable ranking metrics, contributor activity over time, and recommendation evidence. Contributor records with the exact same display name are grouped for report scoring and labelled with their identity count; the raw analysis cache remains unchanged. Contributor emails are hidden by default and the repository's absolute local path is never included. -EmailDisplay Masked or Full can be selected explicitly. -AssetMode Directory writes adjacent local assets, while Cdn uses a remote D3 script.
Invoke-Pester -Path ./Tests -CIIntegration tests create temporary Git repositories and exercise the public module interface. They cover contributor activity, .mailmap consolidation with raw aliases, mailmap-aware cache reuse, range filtering, cross-folder renames, binary files, Unicode/tabbed filenames, literal Unix backslashes, case-distinct directories, and historical-author versus recent-maintainer scoring.
- Analysis currently reads the selected repository's full non-merge history when its cache is invalid. Incremental commit processing and streaming history parsing are not implemented, so very large histories may require substantial memory.
- Explicit
.codeownership.jsoncontributor mappings and exclusion rules are not implemented yet. - Optional blame, co-author attribution, bot/bulk-change filtering, alias suggestions, and suggested
CODEOWNERSexport are deferred. - Activity is aggregated monthly by default. Week and quarter buckets are supported, but day-level reconstruction is intentionally not provided.
- The thin CLI dispatcher is not implemented yet; use the exported PowerShell commands directly.
- Contributor emails are retained in the analysis cache for identity diagnostics; do not publish the raw cache. Generated reports hide them by default.
The date range describes activity within the selected period. It does not reconstruct ownership as it existed at a historical point in time.