diff --git a/lib/git/base.rb b/lib/git/base.rb index bcec10e6..4f961441 100644 --- a/lib/git/base.rb +++ b/lib/git/base.rb @@ -504,8 +504,23 @@ def write_and_commit_tree(opts = {}) def update_ref(branch, commit) branch(branch).update_ref(commit) end - - + + def ls_remote(location = nil, opts = {}) + tmp = self.lib.ls_remote(location, opts) + ret = [] + tmp.each { |line| + split = line.split + if (opts[:tags]) + short_name = split[1].sub(/refs\/tags\//, '') + obj = {:sha => split[0], :tag_ref => split[1], :name => short_name} + else + obj = {:sha => split[0], :ref => split[1]} + end + ret.push obj + return ret + } + end + def ls_files(location=nil) self.lib.ls_files(location) end diff --git a/lib/git/lib.rb b/lib/git/lib.rb index 975bc148..1f200fae 100644 --- a/lib/git/lib.rb +++ b/lib/git/lib.rb @@ -305,7 +305,16 @@ def diff_files def diff_index(treeish) diff_as_hash('diff-index', treeish) end - + + def ls_remote(location = nil, opts = {}) + args = [] + if (opts != {}) + args << (opts[:tags] ? '--tags' : '') + end + args << location + command_lines('ls-remote', args) + end + def ls_files(location=nil) hsh = {} command_lines('ls-files', ['--stage', location]).each do |line| diff --git a/tests/files/working.git/refs/heads/master b/tests/files/working.git/refs/heads/master index 6f2e7bdb..a92a141b 100644 --- a/tests/files/working.git/refs/heads/master +++ b/tests/files/working.git/refs/heads/master @@ -1 +1 @@ -5e392652a881999392c2757cf9b783c5d47b67f7 +9f75a00e575356b1f85247ca33a1a751cd1325a5 diff --git a/tests/units/test_ls_remote.rb b/tests/units/test_ls_remote.rb new file mode 100644 index 00000000..1d1e6dc6 --- /dev/null +++ b/tests/units/test_ls_remote.rb @@ -0,0 +1,85 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../test_helper' + +class TestRemoteLs < Test::Unit::TestCase + def setup + set_file_paths + end + + def test_remote_ls + file_name = "test_remote_ls_tags.file" + in_temp_dir do |path| + r1 = Git.clone(@wbare, 'repo1') + r2 = Git.init('repo2', :bare => true) + + # setup + r1.add_remote('r2', r2) + create_file('repo1/' + file_name, 'content tets_file_1') + r1.add(file_name) + r1.commit_all('test_add/test_remote_ls_tags') + r1.push('origin', 'master') + r1.push('r2', 'master') + + # add a second file + file_name += '2' + create_file('repo1/' + file_name, 'content tets_file_1') + r1.add(file_name) + r1.commit_all('test_add/test_remote_ls_tags') + r1.push('origin', 'master') + + # this is the sha for the second commit + test_file_sha = r1.log(1)[0].sha + + refs = r1.ls_remote('r2') + refs.each { |r| + assert_false r.has_value? test_file_sha + } + + r1.push('r2', 'master') + refs = r1.ls_remote('r2') + + found = false + refs.each { |r| + # the r2 HEAD must point at the local sha captured + if r[:ref] == "HEAD" + assert_equal test_file_sha, r[:sha] + found = true + end + } + assert (found === true), "Expected sha was not found in remote!" + end + end + + def test_remote_ls_tags + in_temp_dir do |path| + r1 = Git.clone(@wbare, 'repo1') + r2 = Git.init('repo2', :bare => true) + + # setup + tag_name = 'foo_bar_bazz' + r1.add_remote('r2', r2) + r1.add_tag(tag_name) + test_sha = r1.log(1)[0].sha + + tags = r1.ls_remote('r2', {:tags => true}) + tags.each { |t| + assert_false t.has_value? tag_name + } + + r1.push('origin', 'master', {:tags => true}) + r1.push('r2', 'master', {:tags => true}) + tags = r1.ls_remote('r2', {:tags => true}) + + found = false + tags.each { |t| + if t[:sha] == test_sha + assert_equal t[:name], tag_name + assert_equal t[:tag_ref], "refs/tags/#{tag_name}" + found = true + end + } + assert (found === true), "Tag was not found in remote!" + end + end +end