own commit attribution
There is no GitHost-style user manifest. GitHub stores one JSON blob per (repo, user, push).
CACHE_VERSION = v2
gh:attr:v2:{full_name}:{username}:{version_token}
version_token is repo.pushed_at, else updated_at, else "head". A new push changes the key. Old blobs die by TTL (default 7 days, ATTRIBUTION_CACHE_TTL_SECONDS).
A truncated measurement is returned for this response and not cached. Only a finished repo walk is written.
Deadlines#
| Env | Default | Used by |
|---|---|---|
ATTRIBUTION_INLINE_DEADLINE |
3.5s | /languages, /stats |
ATTRIBUTION_BREAKDOWN_DEADLINE |
8s | /contributions/breakdown |
ATTRIBUTION_RATE_LIMIT_FLOOR |
500 | stop when GitHub remaining drops below this |
ATTRIBUTION_MAX_COMMITS_PER_REPO |
200 | SHA listing cap |
ATTRIBUTION_MAX_COMMIT_DETAILS |
600 | whole-user budget |
ATTRIBUTION_CONCURRENCY |
10 | commit-detail semaphore |
ATTRIBUTION_REPO_CONCURRENCY |
6 | repos at once |
Deadline gates starting more HTTP, not in-flight work. /{username}/repos never walks. It reads the cache with cache_only=True and budget 0.
How a repo is measured#
get_user_contributions lists repos (sort=pushed, type=all), skips archived (and forks if include_forks=false), newest first, then analyze_repo_contribution:
- Cache hit.
WalkProgress.resolved++. cache_onlyor deadline expired.deferred++, returnNone.- List commit SHAs, maybe count via Link
rel="last". - Fetch files per SHA. Skip vendored paths (
node_modules,dist, lockfiles, minified). - Contributor totals for exact user vs repo additions.
RepoContribution.method:
commits: full own-commit diffsestimated: sample mix scaled by contributor-stat additionscontributor_stats: exact user line totals, empty language list
Whole-repo GET /languages is never used to invent a mix. tests/test_language_fallback.py fails if attributed mode touches get_language_stats.
status on the breakdown: complete, deadline, rate_limited, cache_disabled. coverage = resolved / (resolved + deferred). partial is true when deferred > 0.
Warmer#
python scripts/warm_attribution.py tashifkhan --passes 10 --deadline 60
Needs GITHUB_TOKEN and Redis. Default deadline is 60s, not the inline 3.5s. Or hit /tashifkhan/contributions/breakdown until coverage is 1.