diff --git a/features/compare.feature b/features/compare.feature index 7b7157468cdc6dddb4b15c792b0f697d517aa670..99ad3fd42fe3dd4ada7a30509e55b69aa189214d 100644 --- a/features/compare.feature +++ b/features/compare.feature @@ -13,6 +13,11 @@ Feature: hub compare Then there should be no output And "open https://github.com/mislav/dotfiles/compare/feature/foo" should be run + Scenario: Compare branch with funky characters + When I successfully run `hub compare 'my#branch!with.special+chars'` + Then there should be no output + And "open https://github.com/mislav/dotfiles/compare/my%23branch!with.special%2Bchars" should be run + Scenario: No args, no upstream When I run `hub compare` Then the exit status should be 1 @@ -38,6 +43,13 @@ Feature: hub compare Then there should be no output And "open https://github.com/mislav/dotfiles/compare/experimental" should be run + Scenario: Current branch has funky characters + Given I am on the "feature" branch with upstream "origin/my#branch!with.special+chars" + And git "push.default" is set to "upstream" + When I successfully run `hub compare` + Then there should be no output + And "open https://github.com/mislav/dotfiles/compare/my%23branch!with.special%2Bchars" should be run + Scenario: Compare range When I successfully run `hub compare 1.0...fix` Then there should be no output diff --git a/lib/hub/commands.rb b/lib/hub/commands.rb index d98a0fa69d56adcd41030771df757924793078fc..763287d10ed17e2fb8dcf1a9cb8a8d5748f1d45b 100644 --- a/lib/hub/commands.rb +++ b/lib/hub/commands.rb @@ -704,9 +704,9 @@ module Hub path = case subpage when 'commits' - "/commits/#{branch_in_url(branch)}" + "/commits/#{branch_in_url(branch.short_name)}" when 'tree', NilClass - "/tree/#{branch_in_url(branch)}" if branch and !branch.master? + "/tree/#{branch_in_url(branch.short_name)}" if branch and !branch.master? else "/#{subpage}" end @@ -742,7 +742,8 @@ module Hub end end - path = '/compare/%s' % range + escaped_range = range.include?('..') ? range : branch_in_url(range) + path = '/compare/%s' % escaped_range project.web_url(path, api_client.config.method(:protocol)) end end @@ -842,8 +843,10 @@ module Hub # from the command line. # - def branch_in_url(branch) - CGI.escape(branch.short_name).gsub("%2F", "/") + def branch_in_url(branch_name) + branch_name.to_str.gsub(/[^\w!.*'():^~\/-]/) do |char| + '%' + char.unpack('H2' * char.bytesize).join('%').upcase + end end def api_client