From 970eac1530081e4d56614b4c865fe1c5aae9532b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 3 Jun 2025 14:03:38 +0200 Subject: [PATCH] [rubygems/rubygems] Fix git source unlocking for multi-gem repositories like Rails If you have ``` gem "rails", git: "https://github.com/rails/rails" ``` and then explicitly pin to an older ref, like ``` gem "rails", git: "https://github.com/rails/rails", ref: "https://github.com/rubygems/rubygems/commit/99bacb5aa8e5" ``` Then `bundle install` fails, because locked sources fail to be updated to use the new source. This commit fixes the problem by making sure get their source properly replaced. https://github.com/rubygems/rubygems/commit/5de8c2e0cf --- lib/bundler/definition.rb | 2 +- lib/bundler/source_list.rb | 6 +----- spec/bundler/install/gemfile/git_spec.rb | 24 ++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index e9b67005a9..1a3cf9d6db 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -1045,7 +1045,7 @@ module Bundler s.source = gemfile_source else # Replace the locked dependency's source with the default source, if the locked source is no longer in the Gemfile - s.source = default_source unless sources.get(lockfile_source) + s.source = sources.get(lockfile_source) || default_source end source = s.source diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb index d1308b1dfb..2f16281045 100644 --- a/lib/bundler/source_list.rb +++ b/lib/bundler/source_list.rb @@ -103,7 +103,7 @@ module Bundler end def get(source) - source_list_for(source).find {|s| equivalent_source?(source, s) } + source_list_for(source).find {|s| s.include?(source) } end def lock_sources @@ -265,9 +265,5 @@ module Bundler def equivalent_sources?(lock_sources, replacement_sources) lock_sources.sort_by(&:identifier) == replacement_sources.sort_by(&:identifier) end - - def equivalent_source?(source, other_source) - source == other_source - end end end diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb index c763da4c00..ac64d03e9b 100644 --- a/spec/bundler/install/gemfile/git_spec.rb +++ b/spec/bundler/install/gemfile/git_spec.rb @@ -1151,6 +1151,30 @@ RSpec.describe "bundle install with git sources" do expect(the_bundle).to include_gem "rails 7.1.4", "activesupport 7.1.4" end + + it "doesn't explode when adding an explicit ref to a git gem with dependencies" do + lib_root = lib_path("rails") + + build_lib "activesupport", "7.1.4", path: lib_root.join("activesupport") + build_git "rails", "7.1.4", path: lib_root do |s| + s.add_dependency "activesupport", "= 7.1.4" + end + + old_revision = revision_for(lib_root) + update_git "rails", "7.1.4", path: lib_root + + install_gemfile <<-G + source "https://gem.repo1" + gem "rails", "7.1.4", :git => "#{lib_root}" + G + + install_gemfile <<-G + source "https://gem.repo1" + gem "rails", :git => "#{lib_root}", :ref => "#{old_revision}" + G + + expect(the_bundle).to include_gem "rails 7.1.4", "activesupport 7.1.4" + end end describe "bundle install after the remote has been updated" do