diff --git a/lib/hub/context.rb b/lib/hub/context.rb
index <HASH>..<HASH> 100644
--- a/lib/hub/context.rb
+++ b/lib/hub/context.rb
@@ -18,7 +18,8 @@ module Hub
         @executable = executable || 'git'
         # caches output when shelling out to git
         read_proc ||= lambda { |cache, cmd|
-          result = %x{#{command_to_string(cmd)} 2>#{NULL}}.chomp
+          str = command_to_string(cmd)
+          result = silence_stderr { %x{#{str}}.chomp }
           cache[cmd] = $?.success? && !result.empty? ? result : nil
         }
         @cache = Hash.new(&read_proc)
@@ -61,6 +62,14 @@ module Hub
         full_cmd = to_exec(cmd)
         full_cmd.respond_to?(:shelljoin) ? full_cmd.shelljoin : full_cmd.join(' ')
       end
+
+      def silence_stderr
+        oldio = STDERR.dup
+        STDERR.reopen(NULL)
+        yield
+      ensure
+        STDERR.reopen(oldio)
+      end
     end
 
     module GitReaderMethods
Avoid shell redirection to silence stderr when shelling out

Shelling out to `git`, which by itself takes ~6ms, used to consistently
take 8-<I>ms in hub. Due to the number of different data we have to
collect from git, this overhead is the leading cause of slow execution.

Turns out, when we don't use shell redirection, but silence STDERR
ourselves in Ruby, this overhead is gone and the time spent shelling out
is much closer to git execution time.