diff options
-rw-r--r-- | lib/chef/provider/git.rb | 16 | ||||
-rw-r--r-- | spec/functional/resource/git_spec.rb | 22 |
2 files changed, 34 insertions, 4 deletions
diff --git a/lib/chef/provider/git.rb b/lib/chef/provider/git.rb index c8b48f5602..6f5a129820 100644 --- a/lib/chef/provider/git.rb +++ b/lib/chef/provider/git.rb @@ -154,6 +154,11 @@ class Chef sha_hash?(result) ? result : nil end + def already_on_target_branch? + current_branch = git("rev-parse", "--abbrev-ref", "HEAD", cwd: cwd, returns: [0, 128]).stdout.strip + current_branch == (new_resource.checkout_branch || new_resource.revision) + end + def add_remotes if new_resource.additional_remotes.length > 0 new_resource.additional_remotes.each_pair do |remote_name, remote_url| @@ -193,6 +198,9 @@ class Chef # detached head git("checkout", target_revision, cwd: cwd) logger.info "#{new_resource} checked out reference: #{target_revision}" + elsif already_on_target_branch? + # we are already on the proper branch + git("reset", "--hard", target_revision, cwd: cwd) else # need a branch with a tracking branch git("branch", "-f", new_resource.revision, target_revision, cwd: cwd) @@ -222,13 +230,13 @@ class Chef logger.trace "Fetching updates from #{new_resource.remote} and resetting to revision #{target_revision}" git("fetch", "--prune", new_resource.remote, cwd: cwd) git("fetch", new_resource.remote, "--tags", cwd: cwd) - if new_resource.checkout_branch + if sha_hash?(new_resource.revision) || is_tag? || already_on_target_branch? + # detached head or if we are already on the proper branch + git("reset", "--hard", target_revision, cwd: cwd) + elsif new_resource.checkout_branch # check out to a local branch git("branch", "-f", new_resource.checkout_branch, target_revision, cwd: cwd) git("checkout", new_resource.checkout_branch, cwd: cwd) - elsif sha_hash?(new_resource.revision) || is_tag? - # detached head - git("reset", "--hard", target_revision, cwd: cwd) else # need a branch with a tracking branch git("branch", "-f", new_resource.revision, target_revision, cwd: cwd) diff --git a/spec/functional/resource/git_spec.rb b/spec/functional/resource/git_spec.rb index f8064fef20..25e5c6da4a 100644 --- a/spec/functional/resource/git_spec.rb +++ b/spec/functional/resource/git_spec.rb @@ -239,6 +239,28 @@ describe Chef::Resource::Git, requires_git: true do end end + context "when updating a branch that's already checked out out" do + it "checks out master, commits to the repo, and checks out the latest changes" do + git deploy_directory do + repository origin_repo + revision "master" + action :sync + end.should_be_updated + + # We don't have a way to test a commit in the git bundle + # Revert to a previous commit in the same branch and make sure we can still sync. + shell_out!("git", "reset", "--hard", rev_foo, cwd: deploy_directory) + + git deploy_directory do + repository origin_repo + revision "master" + action :sync + end.should_be_updated + expect_revision_to_be("HEAD", rev_head) + expect_branch_to_be("master") + end + end + context "when dealing with a repo with a degenerate tag named 'HEAD'" do before do shell_out!("git", "tag", "-m\"degenerate tag\"", "HEAD", "ed181b3419b6f489bedab282348162a110d6d3a1", cwd: origin_repo) |