diff options
-rw-r--r-- | lib/bundler/source/git/git_proxy.rb | 20 | ||||
-rw-r--r-- | spec/bundler/bundler/source/git/git_proxy_spec.rb | 10 | ||||
-rw-r--r-- | spec/bundler/install/gemfile/git_spec.rb | 11 |
3 files changed, 33 insertions, 8 deletions
diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb index 2a2b48053a..3a6a666627 100644 --- a/lib/bundler/source/git/git_proxy.rb +++ b/lib/bundler/source/git/git_proxy.rb @@ -28,8 +28,9 @@ module Bundler def initialize(command, path, extra_info = nil) @command = command - msg = String.new - msg << "Git error: command `#{command}` in directory #{path} has failed." + msg = String.new("Git error: command `#{command}`") + msg << " in directory #{path}" if path + msg << " has failed." msg << "\n#{extra_info}" if extra_info super msg end @@ -153,9 +154,20 @@ module Bundler SharedHelpers.filesystem_access(path.dirname) do |p| FileUtils.mkdir_p(p) end - git_retry "clone", "--bare", "--no-hardlinks", "--quiet", *extra_clone_args, "--", configured_uri, path.to_s - extra_ref + command = ["clone", "--bare", "--no-hardlinks", "--quiet", *extra_clone_args, "--", configured_uri, path.to_s] + command_with_no_credentials = check_allowed(command) + + Bundler::Retry.new("`#{command_with_no_credentials}`", [MissingGitRevisionError]).attempts do + _, err, status = capture(command, nil) + return extra_ref if status.success? + + if err.include?("Could not find remote branch") + raise MissingGitRevisionError.new(command_with_no_credentials, nil, explicit_ref, credential_filtered_uri) + else + raise GitCommandError.new(command_with_no_credentials, path, err) + end + end end def clone_needs_unshallow? diff --git a/spec/bundler/bundler/source/git/git_proxy_spec.rb b/spec/bundler/bundler/source/git/git_proxy_spec.rb index 841b8651e4..98d54015e7 100644 --- a/spec/bundler/bundler/source/git/git_proxy_spec.rb +++ b/spec/bundler/bundler/source/git/git_proxy_spec.rb @@ -6,13 +6,15 @@ RSpec.describe Bundler::Source::Git::GitProxy do let(:ref) { "HEAD" } let(:revision) { nil } let(:git_source) { nil } + let(:clone_result) { double(Process::Status, :success? => true) } + let(:base_clone_args) { ["clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--depth", "1", "--single-branch"] } subject { described_class.new(path, uri, ref, revision, git_source) } context "with configured credentials" do it "adds username and password to URI" do Bundler.settings.temporary(uri => "u:p") do allow(subject).to receive(:git).with("--version").and_return("git version 2.14.0") - expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--depth", "1", "--single-branch", "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s) + expect(subject).to receive(:capture).with([*base_clone_args, "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result]) subject.checkout end end @@ -20,7 +22,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do it "adds username and password to URI for host" do Bundler.settings.temporary("github.com" => "u:p") do allow(subject).to receive(:git).with("--version").and_return("git version 2.14.0") - expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--depth", "1", "--single-branch", "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s) + expect(subject).to receive(:capture).with([*base_clone_args, "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result]) subject.checkout end end @@ -28,7 +30,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do it "does not add username and password to mismatched URI" do Bundler.settings.temporary("https://u:p@github.com/rubygems/rubygems-mismatch.git" => "u:p") do allow(subject).to receive(:git).with("--version").and_return("git version 2.14.0") - expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--depth", "1", "--single-branch", "--", uri, path.to_s) + expect(subject).to receive(:capture).with([*base_clone_args, "--", uri, path.to_s], nil).and_return(["", "", clone_result]) subject.checkout end end @@ -38,7 +40,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do original = "https://orig:info@github.com/rubygems/rubygems.git" subject = described_class.new(Pathname("path"), original, "HEAD") allow(subject).to receive(:git).with("--version").and_return("git version 2.14.0") - expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--depth", "1", "--single-branch", "--", original, path.to_s) + expect(subject).to receive(:capture).with([*base_clone_args, "--", original, path.to_s], nil).and_return(["", "", clone_result]) subject.checkout end end diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb index b6ea32819b..e3be680d89 100644 --- a/spec/bundler/install/gemfile/git_spec.rb +++ b/spec/bundler/install/gemfile/git_spec.rb @@ -1144,6 +1144,17 @@ RSpec.describe "bundle install with git sources" do G expect(err).to include("Revision deadbeef does not exist in the repository") end + + it "gives a helpful error message when the remote branch no longer exists" do + build_git "foo" + + install_gemfile <<-G, :raise_on_error => false + source "#{file_uri_for(gem_repo1)}" + gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :branch => "deadbeef" + G + + expect(err).to include("Revision deadbeef does not exist in the repository") + end end describe "bundle install with deployment mode configured and git sources" do |