Skip to content

Cache a shared git source only once per command#9689

Open
hsbt wants to merge 1 commit into
masterfrom
claude/rubygems-issue-8592-400903
Open

Cache a shared git source only once per command#9689
hsbt wants to merge 1 commit into
masterfrom
claude/rubygems-issue-8592-400903

Conversation

@hsbt

@hsbt hsbt commented Jul 14, 2026

Copy link
Copy Markdown
Member

When multiple gems come from a single git block, Runtime#cache invokes the shared Source::Git instance once per gem. cache_to had no idempotency, so it removed the just written cache and re-ran git_proxy.copy_to, cloning and checking out the whole worktree every time. For large repositories such as rails this made bundle cache, bundle update, and bundle install noticeably 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

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>
Copilot AI review requested due to automatic review settings July 14, 2026 07:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_to and skip redundant copies within the same command.
  • Add a unit spec ensuring #cache only 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.

Comment thread spec/cache/git_spec.rb
expect(the_bundle).to include_gems "foo 1.0"
end

it "caches a repository shared by multiple gems only once" do
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bundler re-fetches git repo multiple times during cache / update if multiple gems refer to the same repo

2 participants