summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/chef/provider/git.rb16
-rw-r--r--spec/functional/resource/git_spec.rb22
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)