diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -47,6 +47,7 @@
     'ArcanistBrowseObjectNameURIHardpointLoader' => 'browse/loader/ArcanistBrowseObjectNameURIHardpointLoader.php',
     'ArcanistBrowsePathURIHardpointLoader' => 'browse/loader/ArcanistBrowsePathURIHardpointLoader.php',
     'ArcanistBrowseRef' => 'browse/ref/ArcanistBrowseRef.php',
+    'ArcanistBrowseRevisionURIHardpointLoader' => 'browse/loader/ArcanistBrowseRevisionURIHardpointLoader.php',
     'ArcanistBrowseURIHardpointLoader' => 'browse/loader/ArcanistBrowseURIHardpointLoader.php',
     'ArcanistBrowseURIRef' => 'browse/ref/ArcanistBrowseURIRef.php',
     'ArcanistBrowseWorkflow' => 'browse/workflow/ArcanistBrowseWorkflow.php',
@@ -168,6 +169,7 @@
     'ArcanistGeneratedLinterTestCase' => 'lint/linter/__tests__/ArcanistGeneratedLinterTestCase.php',
     'ArcanistGetConfigWorkflow' => 'workflow/ArcanistGetConfigWorkflow.php',
     'ArcanistGitAPI' => 'repository/api/ArcanistGitAPI.php',
+    'ArcanistGitCommitMessageHardpointLoader' => 'loader/ArcanistGitCommitMessageHardpointLoader.php',
     'ArcanistGitHardpointLoader' => 'loader/ArcanistGitHardpointLoader.php',
     'ArcanistGitLandEngine' => 'land/ArcanistGitLandEngine.php',
     'ArcanistGitRevisionHardpointLoader' => 'loader/ArcanistGitRevisionHardpointLoader.php',
@@ -487,6 +489,7 @@
     'ArcanistBrowseObjectNameURIHardpointLoader' => 'ArcanistBrowseURIHardpointLoader',
     'ArcanistBrowsePathURIHardpointLoader' => 'ArcanistBrowseURIHardpointLoader',
     'ArcanistBrowseRef' => 'ArcanistRef',
+    'ArcanistBrowseRevisionURIHardpointLoader' => 'ArcanistBrowseURIHardpointLoader',
     'ArcanistBrowseURIHardpointLoader' => 'ArcanistHardpointLoader',
     'ArcanistBrowseURIRef' => 'ArcanistRef',
     'ArcanistBrowseWorkflow' => 'ArcanistWorkflow',
@@ -608,6 +611,7 @@
     'ArcanistGeneratedLinterTestCase' => 'ArcanistLinterTestCase',
     'ArcanistGetConfigWorkflow' => 'ArcanistWorkflow',
     'ArcanistGitAPI' => 'ArcanistRepositoryAPI',
+    'ArcanistGitCommitMessageHardpointLoader' => 'ArcanistGitHardpointLoader',
     'ArcanistGitHardpointLoader' => 'ArcanistHardpointLoader',
     'ArcanistGitLandEngine' => 'ArcanistLandEngine',
     'ArcanistGitRevisionHardpointLoader' => 'ArcanistGitHardpointLoader',
diff --git a/src/browse/loader/ArcanistBrowseCommitHardpointLoader.php b/src/browse/loader/ArcanistBrowseCommitHardpointLoader.php
--- a/src/browse/loader/ArcanistBrowseCommitHardpointLoader.php
+++ b/src/browse/loader/ArcanistBrowseCommitHardpointLoader.php
@@ -33,9 +33,6 @@
 
     $commit_map = array();
     foreach ($refs as $key => $ref) {
-      $is_commit = $ref->hasType(
-        ArcanistBrowseCommitURIHardpointLoader::BROWSETYPE);
-
       $token = $ref->getToken();
 
       if ($token === '.') {
@@ -44,14 +41,16 @@
         continue;
       }
 
+      // Always resolve the empty token; top-level loaders filter out
+      // irrelevant tokens before this stage.
       if ($token === null) {
-        if ($is_commit) {
-          $token = $api->getHeadCommit();
-        } else {
-          continue;
-        }
+        $token = $api->getHeadCommit();
       }
 
+      // TODO: We should pull a full commit ref out of the API as soon as it
+      // is able to provide them. In particular, we currently miss Git tree
+      // hashes which reduces the accuracy of lookups.
+
       try {
         $commit = $api->getCanonicalRevisionName($token);
         if ($commit) {
diff --git a/src/browse/loader/ArcanistBrowseCommitURIHardpointLoader.php b/src/browse/loader/ArcanistBrowseCommitURIHardpointLoader.php
--- a/src/browse/loader/ArcanistBrowseCommitURIHardpointLoader.php
+++ b/src/browse/loader/ArcanistBrowseCommitURIHardpointLoader.php
@@ -47,7 +47,6 @@
     }
 
     $refs = $this->getRefsWithSupportedTypes($refs);
-
     if (!$refs) {
       return array();
     }
@@ -80,7 +79,7 @@
         $uri = $commit_ref->getURI();
         if ($uri !== null) {
           $results[$key][] = id(new ArcanistBrowseURIRef())
-            ->setURI()
+            ->setURI($uri)
             ->setType(self::BROWSETYPE);
         }
       }
diff --git a/src/browse/loader/ArcanistBrowseRevisionURIHardpointLoader.php b/src/browse/loader/ArcanistBrowseRevisionURIHardpointLoader.php
new file mode 100644
--- /dev/null
+++ b/src/browse/loader/ArcanistBrowseRevisionURIHardpointLoader.php
@@ -0,0 +1,78 @@
+<?php
+
+final class ArcanistBrowseRevisionURIHardpointLoader
+  extends ArcanistBrowseURIHardpointLoader {
+
+  const LOADERKEY = 'browse.uri.revision';
+  const BROWSETYPE = 'revision';
+
+  public function loadHardpoints(array $refs, $hardpoint) {
+    $query = $this->getQuery();
+
+    $working_ref = $query->getWorkingCopyRef();
+    if (!$working_ref) {
+      return array();
+    }
+
+    $repository_ref = $query->getRepositoryRef();
+    if (!$repository_ref) {
+      return array();
+    }
+
+    $refs = $this->getRefsWithSupportedTypes($refs);
+    if (!$refs) {
+      return array();
+    }
+
+    $this->newQuery($refs)
+      ->needHardpoints(
+        array(
+          'commitRefs',
+        ))
+      ->execute();
+
+    $states = array();
+    $map = array();
+    foreach ($refs as $key => $ref) {
+      foreach ($ref->getCommitRefs() as $commit_ref) {
+        $hash = $commit_ref->getCommitHash();
+        $states[$hash] = id(clone $working_ref)
+          ->setCommitRef($commit_ref);
+        $map[$hash][] = $key;
+      }
+    }
+
+    if (!$states) {
+      return array();
+    }
+
+    $this->newQuery($states)
+      ->needHardpoints(
+        array(
+          'revisionRefs',
+        ))
+      ->execute();
+
+    $results = array();
+    foreach ($states as $hash => $state) {
+      foreach ($state->getRevisionRefs() as $revision) {
+        if ($revision->isClosed()) {
+          // Don't resolve closed revisions.
+          continue;
+        }
+
+        $uri = $revision->getURI();
+
+        foreach ($map[$hash] as $key) {
+          $results[$key][] = id(new ArcanistBrowseURIRef())
+            ->setURI($uri)
+            ->setType(self::BROWSETYPE);
+        }
+      }
+    }
+
+    return $results;
+  }
+
+
+}
diff --git a/src/browse/workflow/ArcanistBrowseWorkflow.php b/src/browse/workflow/ArcanistBrowseWorkflow.php
--- a/src/browse/workflow/ArcanistBrowseWorkflow.php
+++ b/src/browse/workflow/ArcanistBrowseWorkflow.php
@@ -68,13 +68,6 @@
     $console = PhutilConsole::getConsole();
 
     $targets = $this->getArgument('targets');
-    if (!$targets) {
-      throw new ArcanistUsageException(
-        pht(
-          'Specify one or more paths or objects to browse. Use the '.
-          'command "%s" if you want to browse this directory.',
-          'arc browse .'));
-    }
     $targets = array_fuse($targets);
 
     if (!$targets) {
@@ -222,11 +215,19 @@
     // If anything failed to resolve, this is also an error.
     if ($zero_hits) {
       foreach ($zero_hits as $ref) {
-        echo tsprintf(
-          "%s\n",
-          pht(
-            'Unable to resolve argument "%s".',
-            $ref->getToken()));
+        $token = $ref->getToken();
+        if ($token === null) {
+          echo tsprintf(
+            "%s\n",
+            pht(
+              'Unable to resolve default browse target.'));
+        } else {
+          echo tsprintf(
+            "%s\n",
+            pht(
+              'Unable to resolve argument "%s".',
+              $ref->getToken()));
+        }
       }
 
       foreach ($loaders as $loader) {
diff --git a/src/loader/ArcanistGitCommitMessageHardpointLoader.php b/src/loader/ArcanistGitCommitMessageHardpointLoader.php
new file mode 100644
--- /dev/null
+++ b/src/loader/ArcanistGitCommitMessageHardpointLoader.php
@@ -0,0 +1,41 @@
+<?php
+
+final class ArcanistGitCommitMessageHardpointLoader
+  extends ArcanistGitHardpointLoader {
+
+  const LOADERKEY = 'git.commit.message';
+
+  public function canLoadRef(ArcanistRef $ref) {
+    return ($ref instanceof ArcanistCommitRef);
+  }
+
+  public function canLoadHardpoint(ArcanistRef $ref, $hardpoint) {
+    return ($hardpoint == 'message');
+  }
+
+  public function loadHardpoints(array $refs, $hardpoint) {
+    $api = $this->getQuery()->getRepositoryAPI();
+
+
+    $futures = array();
+    foreach ($refs as $ref_key => $ref) {
+      $hash = $ref->getCommitHash();
+
+      $futures[$ref_key] = $api->execFutureLocal(
+        'log -n1 --format=%C %s --',
+        '%s%n%n%b',
+        $hash);
+    }
+
+    $iterator = $this->newFutureIterator($futures);
+
+    $results = array();
+    foreach ($iterator as $ref_key => $future) {
+      list($stdout) = $future->resolvex();
+      $results[$ref_key] = $stdout;
+    }
+
+    return $results;
+  }
+
+}
diff --git a/src/loader/ArcanistGitRevisionHardpointLoader.php b/src/loader/ArcanistGitRevisionHardpointLoader.php
--- a/src/loader/ArcanistGitRevisionHardpointLoader.php
+++ b/src/loader/ArcanistGitRevisionHardpointLoader.php
@@ -33,10 +33,12 @@
         $commit->getCommitHash(),
       );
 
-      $commit_hashes[] = array(
-        'gttr',
-        $commit->getTreeHash(),
-      );
+      if ($commit->getTreeHash()) {
+        $commit_hashes[] = array(
+          'gttr',
+          $commit->getTreeHash(),
+        );
+      }
 
       foreach ($commit_hashes as $hash) {
         $hashes[] = $hash;
diff --git a/src/ref/ArcanistRevisionRef.php b/src/ref/ArcanistRevisionRef.php
--- a/src/ref/ArcanistRevisionRef.php
+++ b/src/ref/ArcanistRevisionRef.php
@@ -28,6 +28,22 @@
     return idx($this->parameters, 'statusName');
   }
 
+  public function isClosed() {
+    // TODO: This should use sensible constants, not English language
+    // display text.
+    switch ($this->getStatusDisplayName()) {
+      case 'Abandoned':
+      case 'Closed':
+        return true;
+    }
+
+    return false;
+  }
+
+  public function getURI() {
+    return idx($this->parameters, 'uri');
+  }
+
   public function getFullName() {
     return pht('%s: %s', $this->getMonogram(), $this->getName());
   }