Cache a shared git source only once per command#9689
Open
hsbt wants to merge 1 commit into
Open
Conversation
When multiple gems come from the same git block, Runtime#cache invokes the shared Source::Git once per gem, and cache_to re-cloned and re-checked out the whole worktree every time. For large repositories this made bundle cache/update/install significantly slower. Memoize the written app cache path and skip the copy when it was already populated during the same command. #8592 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves Bundler’s performance when multiple gems are sourced from the same git block by making Bundler::Source::Git#cache_to idempotent for a given app cache path within a single command execution, avoiding repeated expensive git_proxy.copy_to operations.
Changes:
- Memoize the app cache path written by
Bundler::Source::Git#cache_toand skip redundant copies within the same command. - Add a unit spec ensuring
#cacheonly copies once when multiple gems share a git source. - Add an integration-style cache spec for multiple gems sharing a single git repository cache directory.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| lib/bundler/source/git.rb | Skips repeated copy_to when the same app cache path was already populated during the current command. |
| spec/bundler/source/git_spec.rb | Adds a unit test asserting the repository copy occurs only once across multiple #cache calls. |
| spec/cache/git_spec.rb | Adds an integration-style scenario for caching and installing multiple gems from a shared git repo cache. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| expect(the_bundle).to include_gems "foo 1.0" | ||
| end | ||
|
|
||
| it "caches a repository shared by multiple gems only once" do |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When multiple gems come from a single
gitblock,Runtime#cacheinvokes the sharedSource::Gitinstance once per gem.cache_tohad no idempotency, so it removed the just written cache and re-rangit_proxy.copy_to, cloning and checking out the whole worktree every time. For large repositories such asrailsthis madebundle cache,bundle update, andbundle installnoticeably slower, showing the checkout progress once per gem even though only a single fetch was needed.This memoizes the written app cache path on the source and skips the copy when the same path was already populated during the current command. The revision does not change within a single command run, so re-writing the same path is pure waste.
Fixes #8592