A 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.
Your 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?
It works across many ecosystems (Gemfile, package.json, Dockerfile, GitHub Actions workflows) giving you one unified history instead of separate tools per ecosystem. Everything runs locally and offline with no external services or network calls, and the database lives in your .git directory where you can use it in CI to catch dependency changes in pull requests.
gem install git-pkgscd your-repo
git pkgs init # analyze history (one-time, ~300 commits/sec)
git pkgs list # show current dependencies
git pkgs stats # see overview
git pkgs blame # who added each dependency
git pkgs history # all dependency changes over time
git pkgs history rails # track a specific package
git pkgs why rails # why was this added?
git pkgs diff --from=HEAD~10 # what changed recently?
git pkgs diff --from=main --to=feature # compare branchesgit pkgs initWalks through git history and builds a SQLite database of dependency changes, stored in .git/pkgs.sqlite3.
Options:
--branch=NAME- analyze a specific branch (default: default branch)--since=SHA- start analysis from a specific commit--force- rebuild the database from scratch--no-hooks- skip installing git hooks (hooks are installed by default)
Example output:
Analyzing branch: main
Processing commit 5191/5191...
Done!
Analyzed 5191 commits
Found 2531 commits with dependency changes
Stored 28239 snapshots (every 50 changes)
Blob cache: 3141 unique blobs, 2349 had cache hits
git pkgs infoShows database size and row counts:
Database Info
========================================
Location: /path/to/repo/.git/pkgs.sqlite3
Size: 8.3 MB
Row Counts
----------------------------------------
Branches 1
Commits 3988
Branch-Commits 3988
Manifests 9
Dependency Changes 4732
Dependency Snapshots 28239
----------------------------------
Total 40957
Snapshot Coverage
----------------------------------------
Commits with dependency changes: 2531
Commits with snapshots: 127
Coverage: 2.0% (1 snapshot per ~50 changes)
git pkgs list
git pkgs list --commit=abc123
git pkgs list --ecosystem=rubygemsExample output:
Gemfile (rubygems):
bootsnap >= 0 [runtime]
bootstrap = 4.6.2 [runtime]
bugsnag >= 0 [runtime]
rails = 8.0.1 [runtime]
sidekiq >= 0 [runtime]
...
git pkgs history # all dependency changes
git pkgs history rails # changes for a specific package
git pkgs history --author=alice # filter by author
git pkgs history --since=2024-01-01 # changes after date
git pkgs history --ecosystem=rubygems # filter by ecosystemShows when packages were added, updated, or removed:
History for rails:
2016-12-16 Added = 5.0.0.1
Commit: e323669 Hello World
Author: Andrew Nesbitt <andrew@example.com>
Manifest: Gemfile
2016-12-21 Updated = 5.0.0.1 -> = 5.0.1
Commit: 0c70eee Update rails to 5.0.1
Author: Andrew Nesbitt <andrew@example.com>
Manifest: Gemfile
2024-11-21 Updated = 7.2.2 -> = 8.0.0
Commit: 86a07f4 Upgrade to Rails 8
Author: Andrew Nesbitt <andrew@example.com>
Manifest: Gemfile
Show who added each current dependency:
git pkgs blame
git pkgs blame --ecosystem=rubygems
git pkgs praise # alias for blameExample output:
Gemfile (rubygems):
bootsnap Andrew Nesbitt 2018-04-10 7da4369
bootstrap Andrew Nesbitt 2018-08-02 0b39dc0
bugsnag Andrew Nesbitt 2016-12-23 a87f1bf
factory_bot Lewis Buckley 2017-12-25 f6cceb0
faraday Andrew Nesbitt 2021-11-25 98de229
jwt Andrew Nesbitt 2018-09-10 a39f0ea
octokit Andrew Nesbitt 2016-12-16 e323669
omniauth-rails_csrf_protection dependabot[bot] 2021-11-02 02474ab
rails Andrew Nesbitt 2016-12-16 e323669
sidekiq Mark Tareshawty 2018-02-19 29a1c70
git pkgs stats
git pkgs stats --by-author # who added the most dependencies
git pkgs stats --ecosystem=npm # filter by ecosystem
git pkgs stats --since=2024-01-01 # changes after date
git pkgs stats --until=2024-12-31 # changes before dateExample output:
Dependency Statistics
========================================
Branch: main
Commits analyzed: 3988
Commits with changes: 2531
Current Dependencies
--------------------
Total: 250
rubygems: 232
actions: 14
docker: 4
Dependency Changes
--------------------
Total changes: 4732
added: 391
modified: 4200
removed: 141
Most Changed Dependencies
-------------------------
rails (rubygems): 135 changes
pagy (rubygems): 116 changes
nokogiri (rubygems): 85 changes
puma (rubygems): 73 changes
Manifest Files
--------------
Gemfile (rubygems): 294 changes
Gemfile.lock (rubygems): 4269 changes
.github/workflows/ci.yml (actions): 36 changes
git pkgs why railsThis shows the commit that added the dependency along with the author and message.
git pkgs tree
git pkgs tree --ecosystem=rubygemsThis shows dependencies grouped by type (runtime, development, etc).
git pkgs stale # list deps by how long since last touched
git pkgs stale --days=365 # only show deps untouched for a year
git pkgs stale --ecosystem=npm # filter by ecosystem
git pkgs outdated # alias for staleShows 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.
git pkgs diff --from=abc123 --to=def456
git pkgs diff --from=HEAD~10This shows added, removed, and modified packages with version info.
git pkgs show # show dependency changes in HEAD
git pkgs show abc123 # specific commit
git pkgs show HEAD~5 # relative refLike git show but for dependencies. Shows what was added, modified, or removed in a single commit.
git pkgs where rails # find in manifest files
git pkgs where lodash -C 2 # show 2 lines of context
git pkgs where express --ecosystem=npmShows which manifest files declare a package and the exact line:
Gemfile:5:gem "rails", "~> 7.0"
Gemfile.lock:142: rails (7.0.8)
Like grep but scoped to manifest files that git-pkgs knows about.
git pkgs log # recent commits with dependency changes
git pkgs log --author=alice # filter by author
git pkgs log -n 50 # show more commitsLike git log but only shows commits that changed dependencies, with the changes listed under each commit.
After the initial analysis, the database updates automatically via git hooks installed during init. You can also update manually:
git pkgs updateTo manage hooks separately:
git pkgs hooks # show hook status
git pkgs hooks --install # install hooks
git pkgs hooks --uninstall # remove hooksAfter updating git-pkgs, you may need to rebuild the database if the schema has changed:
git pkgs upgradeThis is detected automatically and you'll see a message if an upgrade is needed.
git pkgs schema # human-readable table format
git pkgs schema --format=sql # CREATE TABLE statements
git pkgs schema --format=json # JSON structure
git pkgs schema --format=markdown # markdown tablesUseful for understanding the database structure or generating documentation.
You can run git-pkgs in CI to show dependency changes in pull requests:
# .github/workflows/deps.yml
name: Dependencies
on: pull_request
jobs:
diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
- run: gem install git-pkgs
- run: git pkgs init
- run: git pkgs diff --from=origin/${{ github.base_ref }} --to=HEADInstall a git textconv driver that shows semantic dependency changes instead of raw lockfile diffs:
git pkgs diff-driver --installNow git diff on lockfiles shows a sorted dependency list instead of raw lockfile changes:
diff --git a/Gemfile.lock b/Gemfile.lock
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,3 +1,3 @@
+kamal 1.0.0
-puma 5.0.0
+puma 6.0.0
rails 7.0.0
-sidekiq 6.0.0Use git diff --no-textconv to see the raw lockfile diff. To remove: git pkgs diff-driver --uninstall
Enable tab completion for commands:
# Bash: add to ~/.bashrc
eval "$(git pkgs completions bash)"
# Zsh: add to ~/.zshrc
eval "$(git pkgs completions zsh)"
# Or auto-install to standard completion directories
git pkgs completions installgit-pkgs respects standard git configuration.
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.
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.
Ecosystem filtering lets you limit which package ecosystems are tracked:
git config --add pkgs.ecosystems rubygems
git config --add pkgs.ecosystems npm
git pkgs info --ecosystems # show enabled/disabled ecosystemsIgnored paths let you skip directories or files from analysis:
git config --add pkgs.ignoredDirs third_party
git config --add pkgs.ignoredFiles test/fixtures/package.jsonEnvironment variables:
GIT_DIR- git directory location (standard git variable)GIT_PKGS_DB- database path (default:.git/pkgs.sqlite3)
Benchmarked on an M1 MacBook Pro analyzing octobox (5191 commits, 8 years of history): init takes about 18 seconds at roughly 300 commits/sec, producing an 8.3 MB database. About half the commits (2531) had dependency changes.
Optimizations:
- Bulk inserts with transaction batching (500 commits per transaction)
- Blob SHA caching (75% cache hit rate for repeated manifest content)
- Deferred index creation during bulk load
- Sparse snapshots (every 50 dependency-changing commits) for storage efficiency
- SQLite WAL mode for write performance
git-pkgs uses ecosystems-bibliothecary for parsing, supporting:
Actions, BentoML, Bower, Cargo, CocoaPods, Cog, Conda, CPAN, CRAN, Docker, Dub, DVC, Elm, Go, Haxelib, Homebrew, Julia, Maven, Meteor, MLflow, npm, NuGet, Ollama, Packagist, Pub, PyPI, RubyGems, Shards, Vcpkg
Some ecosystems require remote parsing services and are disabled by default: Carthage, Clojars, Hackage, Hex, SwiftPM. Enable with git config --add pkgs.ecosystems <name>.
SBOM formats (CycloneDX, SPDX) are not supported as they duplicate information from the actual lockfiles.
Bug reports, feature requests, and pull requests are welcome. If you're unsure about a change, open an issue first to discuss it.
Good first contributions: adding tests, improving error messages, or supporting new manifest formats via ecosystems-bibliothecary.
See CONTRIBUTING.md for setup instructions and architecture docs.
AGPL-3.0