{"id":39849813,"url":"https://github.com/git-pkgs/git-pkgs","last_synced_at":"2026-05-22T21:03:15.524Z","repository":{"id":332853313,"uuid":"1135068161","full_name":"git-pkgs/git-pkgs","owner":"git-pkgs","description":" About  A git subcommand for analyzing package/dependency usage in git repositories over time","archived":false,"fork":false,"pushed_at":"2026-01-21T22:50:58.000Z","size":232,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-22T01:53:25.827Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/git-pkgs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-15T15:41:01.000Z","updated_at":"2026-01-22T00:25:11.000Z","dependencies_parsed_at":"2026-01-19T14:02:04.228Z","dependency_job_id":null,"html_url":"https://github.com/git-pkgs/git-pkgs","commit_stats":null,"previous_names":["git-pkgs/git-pkgs"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/git-pkgs/git-pkgs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-pkgs%2Fgit-pkgs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-pkgs%2Fgit-pkgs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-pkgs%2Fgit-pkgs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-pkgs%2Fgit-pkgs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/git-pkgs","download_url":"https://codeload.github.com/git-pkgs/git-pkgs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-pkgs%2Fgit-pkgs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28721989,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T08:27:05.734Z","status":"ssl_error","status_checked_at":"2026-01-24T08:27:01.197Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-18T13:41:07.821Z","updated_at":"2026-05-22T21:03:15.501Z","avatar_url":"https://github.com/git-pkgs.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# git-pkgs\n\nA git subcommand for tracking package dependencies across git history. Analyzes your repository to show when dependencies were added, modified, or removed, who made those changes, and why. This is a rewrite of the [original Ruby version](https://github.com/andrew/git-pkgs).\n\n[Installation](#installation) · [Quick start](#quick-start) · [Commands](#commands) · [Plugins](#plugins) · [Configuration](#configuration) · [Contributing](#contributing)\n\n## Why this exists\n\nYour lockfile shows what dependencies you have, but it doesn't show how you got here, and `git log Gemfile.lock` is useless noise. git-pkgs indexes your dependency history into a queryable database so you can ask questions like: when did we add this? who added it? what changed between these two releases? has anyone touched this in the last year?\n\nFor best results, commit your lockfiles. Manifests show version ranges but lockfiles show what actually got installed, including transitive dependencies.\n\nIt works across many ecosystems (Gemfile, package.json, Dockerfile, GitHub Actions workflows) giving you one unified history instead of separate tools per ecosystem. The database lives in your `.git` directory where you can use it in CI to catch dependency changes in pull requests.\n\nThe core commands (`list`, `history`, `blame`, `diff`, `stale`, etc.) work entirely from your git history with no network access. Additional commands fetch external data: `vulns` checks [OSV](https://osv.dev) for known CVEs, `outdated` and `licenses` query [ecosyste.ms](https://packages.ecosyste.ms/) for registry metadata, and `changelog` fetches upstream changelogs so you can see what changed between versions.\n\n## Installation\n\n```bash\nbrew install git-pkgs\n```\n\nOr download a binary from the [releases page](https://github.com/git-pkgs/git-pkgs/releases).\n\nOr build from source:\n\n```bash\ngo install github.com/git-pkgs/git-pkgs@latest\n```\n\n## Quick start\n\n```bash\ncd your-repo\ngit pkgs init           # analyze history (one-time)\ngit pkgs list           # show current dependencies\ngit pkgs stats          # see overview\ngit pkgs blame          # who added each dependency\ngit pkgs history        # all dependency changes over time\ngit pkgs history rails  # track a specific package\ngit pkgs why rails      # why was this added?\ngit pkgs diff                 # HEAD vs working tree\ngit pkgs diff --from=HEAD~10  # what changed recently?\ngit pkgs diff main..feature   # compare branches\ngit pkgs vulns          # scan for known CVEs\ngit pkgs vulns blame    # who introduced each vulnerability\ngit pkgs outdated       # find packages with newer versions\ngit pkgs changelog lodash -e npm --from 4.17.20 --to 4.17.21  # view changelog\ngit pkgs update         # update all dependencies\ngit pkgs add lodash     # add a package\ngit pkgs why pkg:npm/lodash  # use a PURL instead of -e flag\n```\n\n## Commands\n\n### Initialize the database\n\n```bash\ngit pkgs init\n```\n\nWalks through git history and builds a SQLite database of dependency changes, stored in `.git/pkgs.sqlite3`.\n\nOptions:\n- `--branch=NAME` - analyze a specific branch (default: default branch)\n- `--since=SHA` - start analysis from a specific commit\n- `--force` - rebuild the database from scratch\n- `--no-hooks` - skip installing git hooks (hooks are installed by default)\n\n### Database info\n\n```bash\ngit pkgs info\n```\n\nShows database size and row counts:\n\n```\nDatabase Info\n========================================\n\nLocation: /path/to/repo/.git/pkgs.sqlite3\nSize: 8.3 MB\n\nRow Counts\n----------------------------------------\n  Branches                        1\n  Commits                      3988\n  Branch-Commits               3988\n  Manifests                       9\n  Dependency Changes           4732\n  Dependency Snapshots        28239\n  ----------------------------------\n  Total                       40957\n```\n\n### List dependencies\n\n```bash\ngit pkgs list\ngit pkgs list --commit=abc123\ngit pkgs list --ecosystem=rubygems\ngit pkgs list --manifest=Gemfile\n```\n\nExample output:\n```\nGemfile (rubygems):\n  bootsnap \u003e= 0 [runtime]\n  bootstrap = 4.6.2 [runtime]\n  bugsnag \u003e= 0 [runtime]\n  rails = 8.0.1 [runtime]\n  sidekiq \u003e= 0 [runtime]\n  ...\n```\n\n### View dependency history\n\n```bash\ngit pkgs history                       # all dependency changes\ngit pkgs history rails                 # changes for a specific package\ngit pkgs history pkg:gem/rails         # same thing, using a PURL\ngit pkgs history --author=alice        # filter by author\ngit pkgs history --since=2024-01-01    # changes after date\ngit pkgs history --ecosystem=rubygems  # filter by ecosystem\n```\n\nShows when packages were added, updated, or removed:\n\n```\nHistory for rails:\n\n2016-12-16 Added = 5.0.0.1\n  Commit: e323669 Hello World\n  Author: Andrew Nesbitt \u003candrew@example.com\u003e\n  Manifest: Gemfile\n\n2016-12-21 Updated = 5.0.0.1 -\u003e = 5.0.1\n  Commit: 0c70eee Update rails to 5.0.1\n  Author: Andrew Nesbitt \u003candrew@example.com\u003e\n  Manifest: Gemfile\n\n2024-11-21 Updated = 7.2.2 -\u003e = 8.0.0\n  Commit: 86a07f4 Upgrade to Rails 8\n  Author: Andrew Nesbitt \u003candrew@example.com\u003e\n  Manifest: Gemfile\n```\n\n### Blame\n\nShow who added each current dependency:\n\n```bash\ngit pkgs blame\ngit pkgs blame --ecosystem=rubygems\n```\n\nExample output:\n```\nGemfile (rubygems):\n  bootsnap                        Andrew Nesbitt     2018-04-10  7da4369\n  bootstrap                       Andrew Nesbitt     2018-08-02  0b39dc0\n  bugsnag                         Andrew Nesbitt     2016-12-23  a87f1bf\n  factory_bot                     Lewis Buckley      2017-12-25  f6cceb0\n  faraday                         Andrew Nesbitt     2021-11-25  98de229\n  jwt                             Andrew Nesbitt     2018-09-10  a39f0ea\n  octokit                         Andrew Nesbitt     2016-12-16  e323669\n  omniauth-rails_csrf_protection  dependabot[bot]    2021-11-02  02474ab\n  rails                           Andrew Nesbitt     2016-12-16  e323669\n  sidekiq                         Mark Tareshawty    2018-02-19  29a1c70\n```\n\n### Show statistics\n\n```bash\ngit pkgs stats\ngit pkgs stats --by-author         # who added the most dependencies\ngit pkgs stats --ecosystem=npm     # filter by ecosystem\ngit pkgs stats --since=2024-01-01  # changes after date\ngit pkgs stats --until=2024-12-31  # changes before date\n```\n\nExample output:\n```\nDependency Statistics\n========================================\n\nBranch: main\nCommits analyzed: 3988\nCommits with changes: 2531\n\nCurrent Dependencies\n--------------------\nTotal: 250\n  rubygems: 232\n  actions: 14\n  docker: 4\n\nDependency Changes\n--------------------\nTotal changes: 4732\n  added: 391\n  modified: 4200\n  removed: 141\n\nMost Changed Dependencies\n-------------------------\n  rails (rubygems): 135 changes\n  pagy (rubygems): 116 changes\n  nokogiri (rubygems): 85 changes\n  puma (rubygems): 73 changes\n\nManifest Files\n--------------\n  Gemfile (rubygems): 294 changes\n  Gemfile.lock (rubygems): 4269 changes\n  .github/workflows/ci.yml (actions): 36 changes\n```\n\n### Explain why a dependency exists\n\n```bash\ngit pkgs why rails\ngit pkgs why pkg:gem/rails\n```\n\nThis shows the commit that added the dependency along with the author and message.\n\n### Dependency tree\n\n```bash\ngit pkgs tree\ngit pkgs tree --ecosystem=rubygems\n```\n\nThis shows dependencies grouped by type (runtime, development, etc).\n\n### Find stale dependencies\n\n```bash\ngit pkgs stale                  # list deps by how long since last touched\ngit pkgs stale --days=365       # only show deps untouched for a year\ngit pkgs stale --ecosystem=npm  # filter by ecosystem\n```\n\nShows dependencies sorted by how long since they were last changed in your repo. Useful for finding packages that may have been forgotten or need review.\n\n### Find outdated dependencies\n\n```bash\ngit pkgs outdated               # show packages with newer versions available\ngit pkgs outdated --major       # only major version updates\ngit pkgs outdated --minor       # minor and major updates (skip patch)\ngit pkgs outdated --at v2.0     # what was outdated when we released v2.0?\ngit pkgs outdated --at 2024-03-01  # what was outdated on this date?\n```\n\nChecks package registries (via [ecosyste.ms](https://packages.ecosyste.ms/)) to find dependencies with newer versions available. Major updates are shown in red, minor in yellow, patch in cyan.\n\nThe `--at` flag enables time travel: pass a date (YYYY-MM-DD) or any git ref (tag, branch, commit SHA) to see what was outdated at that point in time. When given a git ref, it uses the commit's date.\n\n### View changelogs\n\n```bash\ngit pkgs changelog lodash -e npm --from 4.17.20 --to 4.17.21\ngit pkgs changelog pkg:cargo/serde --from 1.0.0 --to 1.0.200\ngit pkgs changelog express -e npm   # all entries up to latest\n```\n\nFetches the upstream changelog for a package and shows entries between two versions. Uses [ecosyste.ms](https://packages.ecosyste.ms/) to find the repository and changelog file, then parses it with [git-pkgs/changelog](https://github.com/git-pkgs/changelog). Supports GitHub and GitLab repositories.\n\n### Manage dependencies\n\ngit-pkgs can run package manager commands for you, detecting the right tool from your lockfiles:\n\n```bash\ngit pkgs install              # install from lockfile\ngit pkgs install --frozen     # CI mode (fail if lockfile would change)\ngit pkgs add lodash           # add a package\ngit pkgs add rails --dev      # add as dev dependency\ngit pkgs add lodash 4.17.21   # add specific version\ngit pkgs add pkg:npm/lodash@4.17.21  # same thing, using a PURL\ngit pkgs remove lodash        # remove a package\ngit pkgs remove pkg:npm/lodash       # remove using a PURL\ngit pkgs update               # update all dependencies\ngit pkgs update lodash        # update specific package\ngit pkgs update pkg:npm/lodash       # update using a PURL\ngit pkgs resolve              # print dependency graph\n```\n\nThe `resolve` command runs the package manager's dependency graph command, parses the output into a normalized JSON structure with [PURLs](https://github.com/package-url/purl-spec), and prints the result. Use `--raw` to get the unparsed manager output instead.\n\nSupports 35 package managers including npm, pnpm, yarn, bun, deno, bundler, gem, cargo, go, pip, uv, poetry, conda, composer, mix, rebar3, pub, cocoapods, swift, nuget, maven, gradle, sbt, cabal, stack, opam, luarocks, nimble, shards, cpanm, lein, vcpkg, conan, helm, and brew. The package manager is detected from lockfiles in the current directory.\n\nUse `-m` to override detection, `-x` to pass extra arguments to the underlying tool:\n\n```bash\ngit pkgs install -m pnpm                    # force pnpm\ngit pkgs install -x --legacy-peer-deps      # pass extra flags\ngit pkgs add lodash -x --save-exact         # npm --save-exact\n```\n\n### Browse package source\n\nOpen the source code of an installed package in your editor:\n\n```bash\ngit pkgs browse lodash           # open in $EDITOR\ngit pkgs browse lodash --path    # just print the path\ngit pkgs browse lodash --open    # open in file browser\ngit pkgs browse serde -m cargo   # specify manager\ngit pkgs browse pkg:npm/lodash   # use a PURL\n```\n\nUse `--path` for scripting:\n\n```bash\ncat $(git pkgs browse lodash --path)/package.json\n```\n\nReturns exit code 2 if the package manager doesn't support path lookup.\n\n### Check licenses\n\n```bash\ngit pkgs licenses               # show license for each dependency\ngit pkgs licenses --permissive  # flag copyleft licenses\ngit pkgs licenses --allow=MIT,Apache-2.0  # explicit allow list\ngit pkgs licenses --group       # group output by license\n```\n\nFetches license information from package registries. Exits with code 1 if violations are found, making it suitable for CI.\n\n### Vulnerability scanning\n\nScan dependencies for known CVEs using the [OSV database](https://osv.dev). Because git-pkgs tracks the full history of every dependency change, it provides context that static scanners can't: who introduced a vulnerability, when it was fixed, and how long you were exposed.\n\n```bash\ngit pkgs vulns                  # scan current dependencies\ngit pkgs vulns v1.0.0           # scan at a tag, branch, or commit\ngit pkgs vulns -s high          # only critical and high severity\ngit pkgs vulns -e npm           # filter by ecosystem\ngit pkgs vulns -f sarif         # output for GitHub code scanning\n```\n\nSubcommands for historical analysis:\n\n```bash\ngit pkgs vulns blame            # who introduced each vulnerability\ngit pkgs vulns blame --all-time # include fixed vulnerabilities\ngit pkgs vulns praise           # who fixed vulnerabilities\ngit pkgs vulns praise --summary # author leaderboard\ngit pkgs vulns exposure         # remediation metrics (CRA compliance)\ngit pkgs vulns diff main feature # compare vulnerability state between refs\ngit pkgs vulns log              # commits that introduced or fixed vulns\ngit pkgs vulns history lodash   # vulnerability timeline for a package\ngit pkgs vulns history pkg:npm/lodash  # same thing, using a PURL\ngit pkgs vulns show CVE-2024-1234  # details about a specific CVE\n```\n\nOutput formats: `text` (default), `json`, and `sarif`. SARIF integrates with GitHub Advanced Security:\n\n```yaml\n- run: git pkgs vulns -f sarif \u003e results.sarif\n- uses: github/codeql-action/upload-sarif@v3\n  with:\n    sarif_file: results.sarif\n```\n\nVulnerability data is cached locally and refreshed automatically when stale (\u003e24h). Use `git pkgs vulns sync --refresh` to force an update.\n\n### Integrity verification\n\nShow SHA256 hashes from lockfiles. Modern lockfiles include checksums that verify package contents haven't been tampered with.\n\n```bash\ngit pkgs integrity              # show hashes for current dependencies\ngit pkgs integrity --drift      # detect same version with different hashes\ngit pkgs integrity -f json      # JSON output\n```\n\nThe `--drift` flag scans your history for packages where the same version has different integrity hashes, which could indicate a supply chain issue.\n\n### SBOM export\n\nExport dependencies as a Software Bill of Materials in CycloneDX or SPDX format:\n\n```bash\ngit pkgs sbom                      # CycloneDX JSON (default)\ngit pkgs sbom --type spdx          # SPDX JSON\ngit pkgs sbom -f xml               # XML instead of JSON\ngit pkgs sbom --name my-project    # custom project name\n```\n\nIncludes package URLs (purls), versions, and licenses (fetched from registries). Use `--skip-enrichment` to omit license lookups.\n\n### Diff between commits or working tree\n\n```bash\ngit pkgs diff                             # HEAD vs working tree\ngit pkgs diff --from=abc123 --to=def456   # between two commits\ngit pkgs diff --from=HEAD~10              # HEAD~10 vs working tree\ngit pkgs diff main..feature               # compare branches\ngit pkgs diff --type=development          # only dev dependency changes\ngit pkgs diff --ecosystem=npm             # filter by ecosystem\n```\n\nWith no arguments, compares HEAD against the working tree (like `git diff`). Shows added, removed, and modified packages with version info.\n\n### Diff between files\n\nCompare dependencies between two manifest files directly, without a git repository or database:\n\n```bash\ngit pkgs diff-file Gemfile.lock.old Gemfile.lock\ngit pkgs diff-file /path/to/project-a/package.json /path/to/project-b/package.json\ngit pkgs diff-file before.lock after.lock --filename=Gemfile.lock  # override type detection\ngit pkgs diff-file old.lock new.lock -f json  # JSON output\n```\n\nUseful for comparing dependencies across different projects, archived source code without git history, or repositories using other version control systems.\n\n### Show changes in a commit\n\n```bash\ngit pkgs show              # show dependency changes in HEAD\ngit pkgs show abc123       # specific commit\ngit pkgs show HEAD~5       # relative ref\n```\n\nLike `git show` but for dependencies. Shows what was added, modified, or removed in a single commit.\n\n### Find where a package is declared\n\n```bash\ngit pkgs where rails           # find in manifest files\ngit pkgs where pkg:gem/rails   # find using a PURL\ngit pkgs where lodash -C 2     # show 2 lines of context\ngit pkgs where express --ecosystem=npm\n```\n\nShows which manifest files declare a package and the exact line:\n\n```\nGemfile:5:gem \"rails\", \"~\u003e 7.0\"\nGemfile.lock:142:    rails (7.0.8)\n```\n\nLike `grep` but scoped to manifest files that git-pkgs knows about.\n\n### Package URLs\n\nShow registry URLs for a package (registry page, download, documentation, PURL):\n\n```bash\ngit pkgs urls pkg:cargo/serde@1.0.0           # from a PURL\ngit pkgs urls lodash --ecosystem npm           # from the database\ngit pkgs urls pkg:npm/express@4.19.0 -f json   # JSON output\n```\n\nExample output:\n```\ndocs       https://docs.rs/serde/1.0.0\ndownload   https://static.crates.io/crates/serde/serde-1.0.0.crate\npurl       pkg:cargo/serde@1.0.0\nregistry   https://crates.io/crates/serde/1.0.0\n```\n\nWhen given a PURL, no database is needed. When given a plain package name, the database is searched for a matching dependency and the ecosystem is inferred. Use `--ecosystem` to disambiguate when a name appears in multiple ecosystems.\n\nMost commands that take a package name also accept PURLs. A PURL like `pkg:npm/lodash@4.17.21` replaces both the package name and `--ecosystem` flag. For example, `git pkgs why pkg:npm/lodash` is equivalent to `git pkgs why lodash -e npm`. Commands that accept PURLs: `why`, `history`, `where`, `browse`, `add`, `remove`, `update`, `urls`, and `vulns history`.\n\n### Search dependencies\n\n```bash\ngit pkgs search rails            # find dependencies matching a pattern\ngit pkgs search react --ecosystem=npm\ngit pkgs search \"^post\" --direct # only direct dependencies, not lockfile\n```\n\nSearches the database for dependencies whose names match the given pattern. Shows the matching name, version requirement, ecosystem, and when the dependency was first seen and last changed.\n\n### List commits with dependency changes\n\n```bash\ngit pkgs log                  # recent commits with dependency changes\ngit pkgs log --author=alice   # filter by author\ngit pkgs log -n 50            # show more commits\n```\n\nLike `git log` but only shows commits that changed dependencies, with the changes listed under each commit.\n\n### Bisect dependency changes\n\nFind when a dependency-related change was introduced using binary search, similar to `git bisect` but only considering commits that changed dependencies:\n\n```bash\ngit pkgs bisect start\ngit pkgs bisect bad HEAD                    # current version has the problem\ngit pkgs bisect good v1.0.0                 # this version was fine\n# git-pkgs checks out a commit with dependency changes\ngit pkgs bisect good                        # or bad, depending on your test\n# repeat until found\ngit pkgs bisect reset                       # end session\n```\n\nAutomate with a script:\n\n```bash\ngit pkgs bisect start HEAD v1.0.0\ngit pkgs bisect run sh -c 'capslock | grep -q NETWORK \u0026\u0026 exit 1 || exit 0'\n```\n\nThis finds when dependencies gained NETWORK capabilities. Exit codes: 0 = good, 1-124 = bad, 125 = skip.\n\nFind when a GPL license was introduced:\n\n```bash\ngit pkgs bisect start HEAD v1.0.0\ngit pkgs bisect run sh -c 'git pkgs licenses --allow=MIT,Apache-2.0 \u003e/dev/null 2\u003e\u00261'\n```\n\nNarrow the search with filters:\n\n```bash\ngit pkgs bisect start --ecosystem=npm HEAD v1.0.0      # only npm changes\ngit pkgs bisect start --package=lodash HEAD v1.0.0     # only lodash changes\ngit pkgs bisect start --manifest=package.json HEAD v1.0.0\n```\n\nSee `docs/bisect.md` for detailed examples and use cases.\n\n### Keep database updated\n\nAfter the initial analysis, the database updates automatically via git hooks installed during init. You can also update manually:\n\n```bash\ngit pkgs reindex\n```\n\nTo manage hooks separately:\n\n```bash\ngit pkgs hooks              # show hook status\ngit pkgs hooks --install    # install hooks\ngit pkgs hooks --uninstall  # remove hooks\n```\n\n### Upgrading\n\nAfter updating git-pkgs, you may need to rebuild the database if the schema has changed:\n\n```bash\ngit pkgs upgrade\n```\n\nThis is detected automatically and you'll see a message if an upgrade is needed.\n\n### Show database schema\n\n```bash\ngit pkgs schema                   # human-readable table format\ngit pkgs schema --format=sql      # CREATE TABLE statements\ngit pkgs schema --format=json     # JSON structure\ngit pkgs schema --format=markdown # markdown tables\n```\n\n### GitHub Actions\n\nReusable actions for CI are available at [git-pkgs/actions](https://github.com/git-pkgs/actions):\n\n```yaml\nsteps:\n  - uses: actions/checkout@v4\n    with:\n      fetch-depth: 0\n\n  - uses: git-pkgs/actions/setup@v1\n  - uses: git-pkgs/actions/diff@v1\n  - uses: git-pkgs/actions/vulns@v1\n    with:\n      severity: \"high\"\n  - uses: git-pkgs/actions/licenses@v1\n    with:\n      deny: \"GPL-3.0-only,AGPL-3.0-only\"\n```\n\nSee the [CI/CD docs](https://git-pkgs.dev/docs/ci-cd/) for more examples.\n\n### Diff driver\n\nInstall a git textconv driver that shows semantic dependency changes instead of raw lockfile diffs:\n\n```bash\ngit pkgs diff-driver --install\n```\n\nNow `git diff` on lockfiles shows a sorted dependency list instead of raw lockfile changes:\n\n```diff\ndiff --git a/Gemfile.lock b/Gemfile.lock\n--- a/Gemfile.lock\n+++ b/Gemfile.lock\n@@ -1,3 +1,3 @@\n+kamal 1.0.0 (runtime)\n-puma 5.0.0 (runtime)\n+puma 6.0.0 (runtime)\n rails 7.0.0 (runtime)\n-sidekiq 6.0.0 (runtime)\n```\n\nUse `git diff --no-textconv` to see the raw lockfile diff. To remove: `git pkgs diff-driver --uninstall`\n\n### Shell completions\n\nEnable tab completion for commands:\n\n```bash\n# Bash: add to ~/.bashrc\neval \"$(git pkgs completions bash)\"\n\n# Zsh: add to ~/.zshrc\neval \"$(git pkgs completions zsh)\"\n\n# Or auto-install to standard completion directories\ngit pkgs completions install\n```\n\n### Aliases\n\nCommon commands have shorter alternatives:\n\n- `ls` for `list`\n- `rm` for `remove`\n- `grep` for `search`\n- `find` for `where`\n- `audit` for `vulns`\n- `praise` for `blame`\n\n## Plugins\n\ngit-pkgs supports external plugins following the same convention as git and kubectl. Any executable on your `$PATH` named `git-pkgs-\u003cname\u003e` becomes available as `git pkgs \u003cname\u003e`.\n\n```bash\n# create a plugin\ncat \u003e ~/bin/git-pkgs-hierarchies \u003c\u003c'EOF'\n#!/bin/sh\necho \"custom plugin running with args: $@\"\nEOF\nchmod +x ~/bin/git-pkgs-hierarchies\n\n# use it\ngit pkgs hierarchies --some-flag\n```\n\nPlugins appear in a separate \"Plugin commands\" section in `git pkgs --help`. All arguments and flags are passed through to the plugin unmodified.\n\nIf a plugin name collides with a built-in command, the built-in takes precedence. When the same name exists in multiple `$PATH` directories, the first match wins.\n\n## Configuration\n\ngit-pkgs respects [standard git configuration](https://git-scm.com/docs/git-config).\n\n**Colors** are enabled when writing to a terminal. Disable with `NO_COLOR=1`, `git config color.ui never`, or `git config color.pkgs never` for git-pkgs only.\n\n**Pager** follows git's precedence: `GIT_PAGER` env, `core.pager` config, `PAGER` env, then `less -FRSX`. Use `--no-pager` flag or `git config core.pager cat` to disable.\n\n**Submodules** are ignored by default when scanning the working directory to prevent reporting their dependencies as part of the main repository. Use `--include-submodules` to scan submodules:\n\n```bash\ngit pkgs diff --include-submodules       # include submodule dependencies\ngit pkgs where lodash --include-submodules\n```\n\n**Ecosystem filtering** lets you limit which package ecosystems are tracked:\n\n```bash\ngit config --add pkgs.ecosystems rubygems\ngit config --add pkgs.ecosystems npm\ngit pkgs info --ecosystems  # show enabled/disabled ecosystems\n```\n\n**Ignored paths** let you skip directories or files from analysis:\n\n```bash\ngit config --add pkgs.ignoredDirs third_party\ngit config --add pkgs.ignoredFiles test/fixtures/package.json\n```\n\n**Direct registry mode** skips the ecosyste.ms API and queries package registries directly. Useful for private registries or airgapped environments:\n\n```bash\ngit config pkgs.direct true        # enable globally\ngit config --local pkgs.direct true  # enable for this repo only\nGIT_PKGS_DIRECT=1 git pkgs outdated  # one-off via environment\n```\n\nBy default, git-pkgs uses a hybrid approach: packages with a `repository_url` qualifier in their PURL (indicating a private registry) are queried directly, while public packages go through ecosyste.ms for efficiency.\n\n**Private registries and proxies:** For commands that query registries (`outdated`, `licenses`, SBOM enrichment), git-pkgs extracts registry URLs from lockfiles when available:\n\n- npm: `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `bun.lock` (from `resolved` URLs)\n- pypi: `Pipfile.lock`, `poetry.lock`, `uv.lock` (from source configuration)\n- cargo: `Cargo.lock` (from `source` field)\n- composer: `composer.lock` (from `dist.url`)\n- gem: `Gemfile.lock` (from `remote:` sections)\n\nIf your lockfile points to a private registry (like Artifactory or GitHub Packages), those URLs are used automatically. However, git-pkgs doesn't currently read config files like `.npmrc` or `.pypirc` for registry URLs or credentials. Authenticated private registries aren't supported yet for registry queries.\n\nCommands that run package managers (`install`, `add`, `remove`, `update`) delegate to the actual CLI tools, which respect their native configuration. See the [managers documentation](https://github.com/git-pkgs/managers#configuration-files) for details.\n\n**Environment variables:**\n\n- `GIT_DIR` - git directory location (standard git variable)\n- `GIT_PKGS_DB` - database path (default: `.git/pkgs.sqlite3`)\n- `GIT_PKGS_DIRECT` - set to `1` to query registries directly (skip ecosyste.ms)\n\n**Author mapping** via `.mailmap` is supported. If your repository has a [`.mailmap` file](https://git-scm.com/docs/gitmailmap), author identities are resolved to their canonical names when indexing commits. This helps deduplicate contributors in `blame`, `history`, and `stats` output.\n\n## Supported ecosystems\n\ngit-pkgs uses [github.com/git-pkgs/manifests](https://github.com/git-pkgs/manifests) for parsing, supporting:\n\nActions, Bazel, Cargo, CocoaPods, Composer, Go, Hex, Maven, npm, NuGet, Pub, PyPI, RubyGems, and more.\n\n## Contributing\n\nBug reports, feature requests, and pull requests are welcome. If you're unsure about a change, open an issue first to discuss it.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgit-pkgs%2Fgit-pkgs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgit-pkgs%2Fgit-pkgs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgit-pkgs%2Fgit-pkgs/lists"}