From a213d71ec8d3e75bef909cc5c3f11aaea8b4e94d Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Thu, 15 May 2014 16:47:24 -0700 Subject: Fix detached head state --- lib/puppet/provider/vcsrepo/git.rb | 21 ++++++++++++++++++--- spec/unit/puppet/provider/vcsrepo/git_spec.rb | 11 +++++++---- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index fafe4bf..b4bafbf 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -79,12 +79,18 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) def revision=(desired) checkout(desired) - if local_branch_revision?(desired) + if local_branch_revision? # reset instead of pull to avoid merge conflicts. assuming remote is # authoritative. # might be worthwhile to have an allow_local_changes param to decide # whether to reset or pull when we're ensuring latest. - at_path { git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") } + at_path { + git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{@resource.value(:revision)}") + if detached? + git_with_identity('checkout', "#{@resource.value(:revision)}") + git_with_identity('pull') + end + } end if @resource.value(:ensure) != :bare update_submodules @@ -259,7 +265,16 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end def on_branch? - at_path { git_with_identity('rev-parse', '--abbrev-ref', 'HEAD').chomp } + at_path { + matches = git_with_identity('branch', '--list').match /\*\s+(.*)/ + matches[1] unless matches[1].match /detached/ + } + end + + def detached? + at_path { + git_with_identity('branch', '--list').match /\*\s+\(detached from.*\)/ + } end def tags diff --git a/spec/unit/puppet/provider/vcsrepo/git_spec.rb b/spec/unit/puppet/provider/vcsrepo/git_spec.rb index ad6ed08..20aa084 100644 --- a/spec/unit/puppet/provider/vcsrepo/git_spec.rb +++ b/spec/unit/puppet/provider/vcsrepo/git_spec.rb @@ -261,6 +261,7 @@ describe Puppet::Type.type(:vcsrepo).provider(:git_provider) do it "should use 'git fetch' and 'git reset'" do resource[:revision] = 'feature/foo' provider.expects(:update_submodules) + provider.expects(:git).with('branch','--list').returns("* master") provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) provider.expects(:git).with('checkout', '--force', resource.value(:revision)) provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) @@ -272,6 +273,7 @@ describe Puppet::Type.type(:vcsrepo).provider(:git_provider) do it "should use 'git fetch' and 'git reset'" do resource[:revision] = 'only/remote' provider.expects(:update_submodules) + provider.expects(:git).with('branch','--list').returns("* master") provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) provider.expects(:git).with('checkout', '--force', resource.value(:revision)) provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) @@ -341,7 +343,7 @@ describe Puppet::Type.type(:vcsrepo).provider(:git_provider) do context "retrieving the current revision" do before do expects_chdir - provider.expects(:git).with('rev-parse', '--abbrev-ref', 'HEAD').returns("foo\n") + provider.expects(:git).with('branch','--list').returns("* foo") end it "will strip trailing newlines" do @@ -377,19 +379,20 @@ describe Puppet::Type.type(:vcsrepo).provider(:git_provider) do end context 'on master' do it do - provider.expects(:git).with('rev-parse', '--abbrev-ref', 'HEAD').returns(fixture(:git_branch_a)) + provider.expects(:git).with('branch','--list').returns("* master") provider.latest.should == 'master' end end context 'no branch' do it do - provider.expects(:git).with('rev-parse', '--abbrev-ref', 'HEAD').returns(fixture(:git_branch_none)) + provider.expects(:git).with('branch','--list').returns("* master") + provider.latest.should == 'master' end end context 'feature/bar' do it do - provider.expects(:git).with('rev-parse', '--abbrev-ref', 'HEAD').returns(fixture(:git_branch_feature_bar)) + provider.expects(:git).with('branch','--list').returns("* master") provider.latest.should == 'master' end end -- cgit v1.2.3