diff --git a/lib/hub/context.rb b/lib/hub/context.rb index 527af63f2..f9b75eba9 100644 --- a/lib/hub/context.rb +++ b/lib/hub/context.rb @@ -194,12 +194,17 @@ def master_branch def remotes @remotes ||= begin - # TODO: is there a plumbing command to get a list of remotes? - list = git_command('remote').to_s.split("\n") - list = ORIGIN_NAMES.inject([]) { |sorted, name| - sorted << list.delete(name) - }.compact.concat(list) - list.map { |name| Remote.new self, name } + names = [] + url_memo = Hash.new {|h,k| names << k; h[k]=[] } + git_command('remote -v').to_s.split("\n").map do |line| + next if line !~ /^(.+?)\t(.+) \(/ + name, url = $1, $2 + url_memo[name] << url + end + ((ORIGIN_NAMES + names) & names).map do |name| + urls = url_memo[name].uniq + Remote.new(self, name, urls) + end end end @@ -376,7 +381,7 @@ def remote_name end end - class Remote < Struct.new(:local_repo, :name) + class Remote < Struct.new(:local_repo, :name, :raw_urls) alias to_s name def ==(other) @@ -384,7 +389,7 @@ def ==(other) end def project - urls.each_value { |url| + urls.each { |url| if valid = GithubProject.from_url(url, local_repo) return valid end @@ -393,21 +398,21 @@ def project end def urls - return @urls if defined? @urls - @urls = {} - local_repo.git_command('remote -v').to_s.split("\n").map do |line| - next if line !~ /^(.+?)\t(.+) \((.+)\)$/ - remote, uri, type = $1, $2, $3 - next if remote != self.name - if uri =~ %r{^[\w-]+://} or uri =~ %r{^([^/]+?):} - uri = "ssh://#{$1}/#{$'}" if $1 + @urls ||= raw_urls.map do |url| + with_normalized_url(url) do |normalized| begin - @urls[type] = uri_parse(uri) + uri_parse(normalized) rescue URI::InvalidURIError end end end - @urls + end + + def with_normalized_url(url) + if url =~ %r{^[\w-]+://} || url =~ %r{^([^/]+?):} + url = "ssh://#{$1}/#{$'}" if $1 + yield url + end end def uri_parse uri diff --git a/test/hub_test.rb b/test/hub_test.rb index 94371fad9..c2f7905a2 100644 --- a/test/hub_test.rb +++ b/test/hub_test.rb @@ -99,7 +99,6 @@ def setup end @git_reader.stub! \ - 'remote' => "mislav\norigin", 'remote -v' => "origin\tgit://github.com/defunkt/hub.git (fetch)\nmislav\tgit://github.com/mislav/hub.git (fetch)", 'rev-parse --symbolic-full-name master@{upstream}' => 'refs/remotes/origin/master', 'config --get --bool hub.http-clone' => 'false', @@ -520,7 +519,7 @@ def stub_remotes_group(name, value) end def stub_no_remotes - stub_command_output 'remote', nil + stub_command_output 'remote -v', nil end def stub_no_git_repo