summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMal Graty <mal.graty@googlemail.com>2014-10-02 00:20:23 +0100
committerMal Graty <mal.graty@googlemail.com>2014-10-02 01:31:11 +0100
commit7c2f066cb6b6245234ea82ff1989438c445bed35 (patch)
treebdd7a3dd15bcbf85599c03b6b6cc34e8e5e12a9a
parentb75e1de72453e20312dcdc1ea1a480c048ee59a9 (diff)
downloadchef-7c2f066cb6b6245234ea82ff1989438c445bed35.tar.gz
Work around breaking change in git
In git 1.7.10 shallow clone behavior was changed from shallow cloning all branches by default, to only shallow cloning the branch being checked out. Unfortunately, this breaks prior and expected behavior in Chef as, on subsequent deploys it is not possible to switch branch, because no other branches exist in the cache-copy of the repo. To fix this we must use the `--no-single-branch` flag when performing the inital clone. Unfortunately this flag is not supported by git versions prior to 1.7.10, so we must check the version of git before deciding if the workaround is required. It probably makes sense to make this prior behavior optional in a future patch, however this one just seeks to give consistent results across all versions of git.
-rw-r--r--lib/chef/provider/git.rb5
-rw-r--r--spec/unit/provider/git_spec.rb15
2 files changed, 20 insertions, 0 deletions
diff --git a/lib/chef/provider/git.rb b/lib/chef/provider/git.rb
index 5b785c31fc..c8e615c1f9 100644
--- a/lib/chef/provider/git.rb
+++ b/lib/chef/provider/git.rb
@@ -102,6 +102,10 @@ class Chef
end
end
+ def git_minor_version
+ @git_minor_version ||= Gem::Version.new(shell_out!('git --version', run_options).stdout.split.last)
+ end
+
def existing_git_clone?
::File.exist?(::File.join(@new_resource.destination, ".git"))
end
@@ -137,6 +141,7 @@ class Chef
args = []
args << "-o #{remote}" unless remote == 'origin'
args << "--depth #{@new_resource.depth}" if @new_resource.depth
+ args << "--no-single-branch" if @new_resource.depth and git_minor_version >= Gem::Version.new('1.7.10')
Chef::Log.info "#{@new_resource} cloning repo #{@new_resource.repository} to #{@new_resource.destination}"
diff --git a/spec/unit/provider/git_spec.rb b/spec/unit/provider/git_spec.rb
index 20b13c4cb0..ff1c0b0398 100644
--- a/spec/unit/provider/git_spec.rb
+++ b/spec/unit/provider/git_spec.rb
@@ -233,6 +233,21 @@ SHAS
it "compiles a clone command using --depth for shallow cloning" do
@resource.depth 5
expected_cmd = "git clone --depth 5 \"git://github.com/opscode/chef.git\" \"/my/deploy/dir\""
+ version_response = double('shell_out')
+ version_response.stub(:stdout) { 'git version 1.7.9' }
+ @provider.should_receive(:shell_out!).with("git --version",
+ :log_tag => "git[web2.0 app]").and_return(version_response)
+ @provider.should_receive(:shell_out!).with(expected_cmd, :log_tag => "git[web2.0 app]")
+ @provider.clone
+ end
+
+ it "compiles a clone command using --no-single-branch for shallow cloning when git >= 1.7.10" do
+ @resource.depth 5
+ expected_cmd = "git clone --depth 5 --no-single-branch \"git://github.com/opscode/chef.git\" \"/my/deploy/dir\""
+ version_response = double('shell_out')
+ version_response.stub(:stdout) { 'git version 1.7.10' }
+ @provider.should_receive(:shell_out!).with("git --version",
+ :log_tag => "git[web2.0 app]").and_return(version_response)
@provider.should_receive(:shell_out!).with(expected_cmd, :log_tag => "git[web2.0 app]")
@provider.clone
end