How it works
Where the repository list comes from, how it is cached, what runs on your machine and what counts against GitHub's rate limits.
Authentication
gh-select has no login of its own. It reads the token for your default host from the GitHub CLI and uses it for the REST and GraphQL APIs. The token is read once per run. When gh has no token, the program exits with could not authenticate with GitHub (run gh auth login).
Deleting repositories is the only feature that needs an extra scope. See Deleting repositories.
The repository list
The list holds every repository you own, belong to through an organization, or collaborate on, de-duplicated and ordered by recent activity. Your repositories and your stars load as parallel REST pages. Fork parents and languages, which the REST listing leaves out, come from one small GraphQL lookup. Around 300 repositories load in about a second.
Each entry carries its visibility, language, star count, last push, license, disk size, fork parent and archived state. Those fields drive the columns, the details block and the filter tokens.
Caching
The list is cached on disk and follows a stale-while-revalidate rule:
- With a cache present, the list renders immediately from it.
- When the cache is older than
GH_SELECT_CACHE_TTLseconds (1800 by default), a refresh runs in the background and the list updates when it finishes. - With no cache, the program fetches first and prints
Loading repositories…, so the screen is never empty.
-n or --no-cache skips the cache and fetches fresh data. gh select refresh refetches and exits, which suits cron jobs. Starred repositories have their own cache, shown instantly and refreshed once per session.
The cache files are versioned. Upgrading to a release that adds repository fields refetches once. See files and paths for the names and the directory.
Local clones
gh-select finds repositories you already cloned and tags them local. The scan runs in the background on every start and is cached in locals.json for the next one, so the tags appear without waiting.
- It searches
GH_SELECT_SCAN_DIRSfirst, then the clone directory, the current directory and your home directory. - A repository is matched by its git remote, so a renamed folder is still recognized. HTTPS, SSH and
ssh://remotes all work. - Git worktrees and submodules count.
- Dependency and cache folders such as
node_modules,vendor,target,dist,build,venv,Libraryandsnapare skipped, and so are hidden folders other than.configand.dotfiles. - One scan reads at most 40000 directories, and a folder with more than 4096 entries is treated as data and skipped.
- When a repository is cloned twice, the most recently used copy wins.
Rate limits
GitHub gives each account separate budgets for search, core REST, GraphQL and code search. Other tools using your gh login draw from the same budgets.
| Bucket | Window | Used by |
|---|---|---|
search | 1 minute | GitHub search scope |
core | 1 hour | Listing, trees, files, releases, downloads |
graphql | 1 hour | Fork parents and languages |
code_search | 1 minute | Shown for completeness |
GitHub search waits until you pause typing for 350 ms before it fires, and fetches a single page of 30 results per query. gh select limits and the ? overlay show usage, how far each window has run, time to reset, and how soon the current pace would empty a bucket. Reading the limits does not count against any of them.
Cloning, saving and downloading
- A clone runs
git clonethrough your owngit, so your SSH keys and credential helpers apply. The URL ishttps://github.com/OWNER/REPO.git. - A partial clone runs
git clone --filter=blob:none --sparse, then a sparse checkout of the marked paths. Folders alone use cone mode. Individual files switch to non-cone patterns anchored at the repository root. Blobs are fetched when needed. - Saving files and downloading release assets use the GitHub API directly and need no git.
- Opening a URL uses
openon macOS,rundll32on Windows, andxdg-openorwslviewelsewhere. Copying usespbcopy,clip.exe,wl-copy,xcliporxsel, whichever exists.
What is written to disk
Only the cache, the saved theme and any files you ask for. gh-select never changes your repositories' contents, and deleting a repository on GitHub never removes a local clone.
Last updated on