diff options
author | Serdar Sutay <serdar@opscode.com> | 2014-10-10 15:28:28 -0700 |
---|---|---|
committer | Serdar Sutay <serdar@opscode.com> | 2014-10-10 15:28:28 -0700 |
commit | 685042c1ea839cef2ad7fe440df1fc0955535581 (patch) | |
tree | edb81ca9f83619055d3ebd56cfb00fa0afcee003 /lib/chef/provider/git.rb | |
parent | 0b44df383395482d96e317babf0546068c30b7ec (diff) | |
parent | eb9b7d065feb003192fcf9295e9a3fc4f8ffe8f3 (diff) | |
download | chef-685042c1ea839cef2ad7fe440df1fc0955535581.tar.gz |
Merge pull request #2079 from jbence/CHEF-2065
Use exact match to locate remote git-reference
Diffstat (limited to 'lib/chef/provider/git.rb')
-rw-r--r-- | lib/chef/provider/git.rb | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/lib/chef/provider/git.rb b/lib/chef/provider/git.rb index c8e615c1f9..2ef119e839 100644 --- a/lib/chef/provider/git.rb +++ b/lib/chef/provider/git.rb @@ -64,7 +64,7 @@ class Chef a.failure_message Chef::Exceptions::UnresolvableGitReference, "Unable to parse SHA reference for '#{@new_resource.revision}' in repository '#{@new_resource.repository}'. " + "Verify your (case-sensitive) repository URL and revision.\n" + - "`git ls-remote` output: #{@resolved_reference}" + "`git ls-remote '#{@new_resource.repository}' '#{rev_search_pattern}'` output: #{@resolved_reference}" end end @@ -240,35 +240,55 @@ class Chef # annotated tags, we have to search for "revision*" and # post-process. Special handling for 'HEAD' to ignore a tag # named 'HEAD'. - rev_pattern = case @new_resource.revision - when '', 'HEAD' - 'HEAD' - else - @new_resource.revision + '*' - end - command = git("ls-remote \"#{@new_resource.repository}\" \"#{rev_pattern}\"") - @resolved_reference = shell_out!(command, run_options).stdout - ref_lines = @resolved_reference.split("\n") - refs = ref_lines.map { |line| line.split("\t") } - # first try for ^{} indicating the commit pointed to by an - # annotated tag - tagged_commit = refs.find { |m| m[1].end_with?("#{@new_resource.revision}^{}") } + @resolved_reference = git_ls_remote(rev_search_pattern) + refs = @resolved_reference.split("\n").map { |line| line.split("\t") } + # First try for ^{} indicating the commit pointed to by an + # annotated tag. # It is possible for a user to create a tag named 'HEAD'. # Using such a degenerate annotated tag would be very # confusing. We avoid the issue by disallowing the use of # annotated tags named 'HEAD'. - if tagged_commit && rev_pattern != 'HEAD' - tagged_commit[0] + if rev_search_pattern != 'HEAD' + found = find_revision(refs, @new_resource.revision, '^{}') else - found = refs.find { |m| m[1].end_with?(@new_resource.revision) } - if found - found[0] - else - nil - end + found = refs_search(refs, 'HEAD') + end + found = find_revision(refs, @new_resource.revision) if found.empty? + found.size == 1 ? found.first[0] : nil + end + + def find_revision(refs, revision, suffix="") + found = refs_search(refs, rev_match_pattern('refs/tags/', revision) + suffix) + found = refs_search(refs, rev_match_pattern('refs/heads/', revision) + suffix) if found.empty? + found = refs_search(refs, revision + suffix) if found.empty? + found + end + + def rev_match_pattern(prefix, revision) + if revision.start_with?(prefix) + revision + else + prefix + revision end end + def rev_search_pattern + if ['', 'HEAD'].include? @new_resource.revision + 'HEAD' + else + @new_resource.revision + '*' + end + end + + def git_ls_remote(rev_pattern) + command = git(%Q(ls-remote "#{@new_resource.repository}" "#{rev_pattern}")) + shell_out!(command, run_options).stdout + end + + def refs_search(refs, pattern) + refs.find_all { |m| m[1] == pattern } + end + private def run_options(run_opts={}) |