diff --git a/src/applications/diffusion/controller/DiffusionHomeController.php b/src/applications/diffusion/controller/DiffusionHomeController.php
index f1f0305fe..a37c58a3c 100644
--- a/src/applications/diffusion/controller/DiffusionHomeController.php
+++ b/src/applications/diffusion/controller/DiffusionHomeController.php
@@ -1,173 +1,208 @@
 <?php
 
 final class DiffusionHomeController extends DiffusionController {
 
   public function processRequest() {
     $request = $this->getRequest();
     $user = $request->getUser();
 
     $shortcuts = id(new PhabricatorRepositoryShortcut())->loadAll();
     if ($shortcuts) {
       $shortcuts = msort($shortcuts, 'getSequence');
 
       $rows = array();
       foreach ($shortcuts as $shortcut) {
         $rows[] = array(
           phutil_render_tag(
             'a',
             array(
               'href' => $shortcut->getHref(),
             ),
             phutil_escape_html($shortcut->getName())),
           phutil_escape_html($shortcut->getDescription()),
         );
       }
 
       $shortcut_table = new AphrontTableView($rows);
       $shortcut_table->setHeaders(
         array(
           'Link',
           '',
         ));
       $shortcut_table->setColumnClasses(
         array(
           'pri',
           'wide',
         ));
 
       $shortcut_panel = new AphrontPanelView();
       $shortcut_panel->setHeader('Shortcuts');
       $shortcut_panel->appendChild($shortcut_table);
     } else {
       $shortcut_panel = null;
     }
 
     $repository = new PhabricatorRepository();
 
     $repositories = $repository->loadAll();
     foreach ($repositories as $key => $repo) {
       if (!$repo->isTracked()) {
         unset($repositories[$key]);
       }
     }
 
     $repository_ids = mpull($repositories, 'getID');
     $summaries = array();
     $commits = array();
     if ($repository_ids) {
       $summaries = queryfx_all(
         $repository->establishConnection('r'),
         'SELECT * FROM %T WHERE repositoryID IN (%Ld)',
         PhabricatorRepository::TABLE_SUMMARY,
         $repository_ids);
       $summaries = ipull($summaries, null, 'repositoryID');
 
       $commit_ids = array_filter(ipull($summaries, 'lastCommitID'));
       if ($commit_ids) {
         $commit = new PhabricatorRepositoryCommit();
         $commits = $commit->loadAllWhere('id IN (%Ld)', $commit_ids);
         $commits = mpull($commits, null, 'getRepositoryID');
       }
     }
 
+    $branch = new PhabricatorRepositoryBranch();
+    $lint_messages = queryfx_all(
+      $branch->establishConnection('r'),
+      'SELECT b.repositoryID, b.name, COUNT(lm.id) AS n
+        FROM %T b
+        LEFT JOIN %T lm ON b.id = lm.branchID
+        GROUP BY b.id',
+      $branch->getTableName(),
+      PhabricatorRepository::TABLE_LINTMESSAGE);
+    $lint_messages = igroup($lint_messages, 'repositoryID');
+
     $rows = array();
+    $show_lint = false;
     foreach ($repositories as $repository) {
       $id = $repository->getID();
       $commit = idx($commits, $id);
 
       $size = idx(idx($summaries, $id, array()), 'size', '-');
       if ($size != '-') {
         $size = hsprintf(
           '<a href="%s">%s</a>',
           DiffusionRequest::generateDiffusionURI(array(
             'callsign' => $repository->getCallsign(),
             'action' => 'history',
           )),
           number_format($size));
       }
 
+      $lint_branches = ipull(idx($lint_messages, $id, array()), 'n', 'name');
+      $branch = $repository->getDefaultArcanistBranch();
+
+      if (isset($lint_branches[$branch])) {
+        $show_lint = true;
+      }
+
       $date = '-';
       $time = '-';
       if ($commit) {
         $date = phabricator_date($commit->getEpoch(), $user);
         $time = phabricator_time($commit->getEpoch(), $user);
       }
 
       $rows[] = array(
         phutil_render_tag(
           'a',
           array(
             'href' => '/diffusion/'.$repository->getCallsign().'/',
           ),
           phutil_escape_html($repository->getName())),
         phutil_escape_html($repository->getDetail('description')),
         PhabricatorRepositoryType::getNameForRepositoryType(
           $repository->getVersionControlSystem()),
         $size,
+        (isset($lint_branches[$branch])
+          ? $lint_branches[$branch]
+          : ''),
         $commit
           ? DiffusionView::linkCommit(
               $repository,
               $commit->getCommitIdentifier())
           : '-',
         $date,
         $time,
       );
     }
 
     $repository_tool_uri = PhabricatorEnv::getProductionURI('/repository/');
     $repository_tool     = phutil_render_tag('a',
                                              array(
                                                'href' => $repository_tool_uri,
                                              ),
                                              'repository tool');
     $no_repositories_txt = 'This instance of Phabricator does not have any '.
                            'configured repositories. ';
     if ($user->getIsAdmin()) {
       $no_repositories_txt .= 'To setup one or more repositories, visit the '.
                               $repository_tool.'.';
     } else {
       $no_repositories_txt .= 'Ask an administrator to setup one or more '.
                               'repositories via the '.$repository_tool.'.';
     }
 
     $table = new AphrontTableView($rows);
     $table->setNoDataString($no_repositories_txt);
     $table->setHeaders(
       array(
         'Repository',
         'Description',
         'VCS',
         'Commits',
+        'Lint',
         'Last',
         'Date',
         'Time',
       ));
     $table->setColumnClasses(
       array(
         'pri',
         'wide',
         '',
         'n',
         'n',
+        'n',
         '',
         'right',
       ));
+    $table->setColumnVisibility(
+      array(
+        true,
+        true,
+        true,
+        true,
+        $show_lint,
+        true,
+        true,
+        true,
+      ));
 
     $panel = new AphrontPanelView();
     $panel->setHeader('Browse Repositories');
     $panel->appendChild($table);
 
     $crumbs = $this->buildCrumbs();
 
     return $this->buildStandardPageResponse(
       array(
         $crumbs,
         $shortcut_panel,
         $panel,
       ),
       array(
         'title' => 'Diffusion',
       ));
   }
 
 }
diff --git a/src/applications/diffusion/controller/DiffusionLastModifiedController.php b/src/applications/diffusion/controller/DiffusionLastModifiedController.php
index ceb92b2d3..64ab74c2c 100644
--- a/src/applications/diffusion/controller/DiffusionLastModifiedController.php
+++ b/src/applications/diffusion/controller/DiffusionLastModifiedController.php
@@ -1,35 +1,35 @@
 <?php
 
 final class DiffusionLastModifiedController extends DiffusionController {
 
   public function processRequest() {
     $drequest = $this->getDiffusionRequest();
     $request = $this->getRequest();
 
     $modified_query = DiffusionLastModifiedQuery::newFromDiffusionRequest(
       $drequest);
     list($commit, $commit_data) = $modified_query->loadLastModification();
 
     $phids = array();
     if ($commit_data) {
       if ($commit_data->getCommitDetail('authorPHID')) {
         $phids[$commit_data->getCommitDetail('authorPHID')] = true;
       }
       if ($commit_data->getCommitDetail('committerPHID')) {
         $phids[$commit_data->getCommitDetail('committerPHID')] = true;
       }
     }
 
     $phids = array_keys($phids);
     $handles = $this->loadViewerHandles($phids);
 
     $output = DiffusionBrowseTableView::renderLastModifiedColumns(
-      $drequest->getRepository(),
+      $drequest,
       $handles,
       $commit,
       $commit_data);
 
     return id(new AphrontAjaxResponse())
       ->setContent($output);
   }
 }
diff --git a/src/applications/diffusion/view/DiffusionBrowseTableView.php b/src/applications/diffusion/view/DiffusionBrowseTableView.php
index 9a962bd90..56eadba0b 100644
--- a/src/applications/diffusion/view/DiffusionBrowseTableView.php
+++ b/src/applications/diffusion/view/DiffusionBrowseTableView.php
@@ -1,245 +1,276 @@
 <?php
 
 final class DiffusionBrowseTableView extends DiffusionView {
 
   private $paths;
   private $handles = array();
   private $user;
 
   public function setPaths(array $paths) {
     assert_instances_of($paths, 'DiffusionRepositoryPath');
     $this->paths = $paths;
     return $this;
   }
 
   public function setHandles(array $handles) {
     assert_instances_of($handles, 'PhabricatorObjectHandle');
     $this->handles = $handles;
     return $this;
   }
 
   public function setUser(PhabricatorUser $user) {
     $this->user = $user;
     return $this;
   }
 
   public static function renderLastModifiedColumns(
-    PhabricatorRepository $repository,
+    DiffusionRequest $drequest,
     array $handles,
     PhabricatorRepositoryCommit $commit = null,
     PhabricatorRepositoryCommitData $data = null) {
     assert_instances_of($handles, 'PhabricatorObjectHandle');
 
     if ($commit) {
       $epoch = $commit->getEpoch();
       $modified = DiffusionView::linkCommit(
-        $repository,
+        $drequest->getRepository(),
         $commit->getCommitIdentifier());
       $date = date('M j, Y', $epoch);
       $time = date('g:i A', $epoch);
     } else {
       $modified = '';
       $date = '';
       $time = '';
     }
 
     if ($data) {
       $author_phid = $data->getCommitDetail('authorPHID');
       if ($author_phid && isset($handles[$author_phid])) {
         $author = $handles[$author_phid]->renderLink();
       } else {
         $author = self::renderName($data->getAuthorName());
       }
 
       $committer = $data->getCommitDetail('committer');
       if ($committer) {
         $committer_phid = $data->getCommitDetail('committerPHID');
         if ($committer_phid && isset($handles[$committer_phid])) {
           $committer = $handles[$committer_phid]->renderLink();
         } else {
           $committer = self::renderName($committer);
         }
         if ($author != $committer) {
           $author .= '/'.$committer;
         }
       }
 
       $details = AphrontTableView::renderSingleDisplayLine(
         phutil_escape_html($data->getSummary()));
     } else {
       $author = '';
       $details = '';
     }
 
-    return array(
+    $return = array(
       'commit'    => $modified,
       'date'      => $date,
       'time'      => $time,
       'author'    => $author,
       'details'   => $details,
     );
+
+    $lint = self::loadLintMessagesCount($drequest);
+    if ($lint !== null) {
+      $return['lint'] = (string)$lint;
+    }
+    return $return;
+  }
+
+  private static function loadLintMessagesCount(DiffusionRequest $drequest) {
+    $branch = $drequest->loadBranch();
+    if (!$branch) {
+      return null;
+    }
+
+    $like = (substr($drequest->getPath(), -1) == '/' ? 'LIKE %>' : '= %s');
+    return head(queryfx_one(
+      $drequest->getRepository()->establishConnection('r'),
+      'SELECT COUNT(*) FROM %T WHERE branchID = %d AND path '.$like,
+      PhabricatorRepository::TABLE_LINTMESSAGE,
+      $branch->getID(),
+      '/'.$drequest->getPath()));
   }
 
   public function render() {
     $request = $this->getDiffusionRequest();
     $repository = $request->getRepository();
 
     $base_path = trim($request->getPath(), '/');
     if ($base_path) {
       $base_path = $base_path.'/';
     }
 
     $need_pull = array();
     $rows = array();
     $show_edit = false;
     foreach ($this->paths as $path) {
 
       $dir_slash = null;
       $file_type = $path->getFileType();
       if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
         $browse_text = $path->getPath().'/';
         $dir_slash = '/';
 
         $browse_link = '<strong>'.$this->linkBrowse(
           $base_path.$path->getPath().$dir_slash,
           array(
             'html' => $this->renderPathIcon(
               'dir',
               $browse_text),
           )).'</strong>';
       } else if ($file_type == DifferentialChangeType::FILE_SUBMODULE) {
         $browse_text = $path->getPath().'/';
         $browse_link =
           '<strong>'.
             $this->linkExternal(
               $path->getHash(),
               $path->getExternalURI(),
               $this->renderPathIcon(
                 'ext',
                 $browse_text)).
           '</strong>';
       } else {
         if ($file_type == DifferentialChangeType::FILE_SYMLINK) {
           $type = 'link';
         } else {
           $type = 'file';
         }
         $browse_text = $path->getPath();
         $browse_link = $this->linkBrowse(
           $base_path.$path->getPath(),
           array(
             'html' => $this->renderPathIcon($type, $browse_text),
           ));
       }
 
       $commit = $path->getLastModifiedCommit();
       if ($commit) {
+        $drequest = clone $request;
+        $drequest->setPath($path->getPath().$dir_slash);
         $dict = self::renderLastModifiedColumns(
-          $repository,
+          $drequest,
           $this->handles,
           $commit,
           $path->getLastCommitData());
       } else {
         $dict = array(
+          'lint'      => celerity_generate_unique_node_id(),
           'commit'    => celerity_generate_unique_node_id(),
           'date'      => celerity_generate_unique_node_id(),
           'time'      => celerity_generate_unique_node_id(),
           'author'    => celerity_generate_unique_node_id(),
           'details'   => celerity_generate_unique_node_id(),
         );
 
         $uri = (string)$request->generateURI(
           array(
             'action' => 'lastmodified',
-            'path'   => $base_path.$path->getPath(),
+            'path'   => $base_path.$path->getPath().$dir_slash,
           ));
 
         $need_pull[$uri] = $dict;
         foreach ($dict as $k => $uniq) {
           $dict[$k] = '<span id="'.$uniq.'"></span>';
         }
       }
 
       $editor_button = '';
       if ($this->user) {
         $editor_link = $this->user->loadEditorLink(
           $base_path.$path->getPath(),
           1,
           $request->getRepository()->getCallsign());
         if ($editor_link) {
           $show_edit = true;
           $editor_button = phutil_render_tag(
             'a',
             array(
               'href' => $editor_link,
             ),
             'Edit');
         }
       }
 
       $rows[] = array(
         $this->linkHistory($base_path.$path->getPath().$dir_slash),
         $editor_button,
         $browse_link,
+        $dict['lint'],
         $dict['commit'],
         $dict['date'],
         $dict['time'],
         $dict['author'],
         $dict['details'],
       );
     }
 
     if ($need_pull) {
       Javelin::initBehavior('diffusion-pull-lastmodified', $need_pull);
     }
 
+    $branch = $this->getDiffusionRequest()->loadBranch();
+    $show_lint = ($branch && $branch->getLintCommit());
+
     $view = new AphrontTableView($rows);
     $view->setHeaders(
       array(
         'History',
         'Edit',
         'Path',
+        'Lint',
         'Modified',
         'Date',
         'Time',
         'Author/Committer',
         'Details',
       ));
     $view->setColumnClasses(
       array(
         '',
         '',
         '',
+        'n',
         '',
         '',
         'right',
         '',
         'wide',
       ));
     $view->setColumnVisibility(
       array(
         true,
         $show_edit,
         true,
+        $show_lint,
         true,
         true,
         true,
         true,
         true,
       ));
     return $view->render();
   }
 
   private function renderPathIcon($type, $text) {
 
     require_celerity_resource('diffusion-icons-css');
 
     return phutil_render_tag(
       'span',
       array(
         'class' => 'diffusion-path-icon diffusion-path-icon-'.$type,
       ),
       phutil_escape_html($text));
   }
 
 }
diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php
index c2301df0b..0512211b5 100644
--- a/src/applications/repository/storage/PhabricatorRepository.php
+++ b/src/applications/repository/storage/PhabricatorRepository.php
@@ -1,588 +1,592 @@
 <?php
 
 /**
  * @task uri Repository URI Management
  */
 final class PhabricatorRepository extends PhabricatorRepositoryDAO {
 
   const TABLE_PATH = 'repository_path';
   const TABLE_PATHCHANGE = 'repository_pathchange';
   const TABLE_FILESYSTEM = 'repository_filesystem';
   const TABLE_SUMMARY = 'repository_summary';
   const TABLE_BADCOMMIT = 'repository_badcommit';
   const TABLE_LINTMESSAGE = 'repository_lintmessage';
 
   protected $phid;
   protected $name;
   protected $callsign;
   protected $uuid;
 
   protected $versionControlSystem;
   protected $details = array();
 
   private $sshKeyfile;
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'details' => self::SERIALIZATION_JSON,
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       PhabricatorPHIDConstants::PHID_TYPE_REPO);
   }
 
   public function getDetail($key, $default = null) {
     return idx($this->details, $key, $default);
   }
 
   public function setDetail($key, $value) {
     $this->details[$key] = $value;
     return $this;
   }
 
   public function getDiffusionBrowseURIForPath($path,
                                                $line = null,
                                                $branch = null) {
     $drequest = DiffusionRequest::newFromDictionary(
       array(
         'repository' => $this,
         'path'       => $path,
         'branch'     => $branch,
       ));
 
     return $drequest->generateURI(
       array(
         'action' => 'browse',
         'line'   => $line,
       ));
   }
 
   public function getLocalPath() {
     return $this->getDetail('local-path');
   }
 
   public function execRemoteCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     $args = $this->formatRemoteCommand($args);
     return call_user_func_array('exec_manual', $args);
   }
 
   public function execxRemoteCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     $args = $this->formatRemoteCommand($args);
     return call_user_func_array('execx', $args);
   }
 
   public function getRemoteCommandFuture($pattern /* , $arg, ... */) {
     $args = func_get_args();
     $args = $this->formatRemoteCommand($args);
     return newv('ExecFuture', $args);
   }
 
   public function passthruRemoteCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     $args = $this->formatRemoteCommand($args);
     return call_user_func_array('phutil_passthru', $args);
   }
 
   public function execLocalCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     $args = $this->formatLocalCommand($args);
     return call_user_func_array('exec_manual', $args);
   }
 
   public function execxLocalCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     $args = $this->formatLocalCommand($args);
     return call_user_func_array('execx', $args);
   }
 
   public function getLocalCommandFuture($pattern /* , $arg, ... */) {
     $args = func_get_args();
     $args = $this->formatLocalCommand($args);
     return newv('ExecFuture', $args);
 
   }
   public function passthruLocalCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     $args = $this->formatLocalCommand($args);
     return call_user_func_array('phutil_passthru', $args);
   }
 
 
   private function formatRemoteCommand(array $args) {
     $pattern = $args[0];
     $args = array_slice($args, 1);
 
     if ($this->shouldUseSSH()) {
       switch ($this->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
           $pattern = "SVN_SSH=%s svn --non-interactive {$pattern}";
           array_unshift(
             $args,
             csprintf(
               'ssh -l %s -i %s',
               $this->getSSHLogin(),
               $this->getSSHKeyfile()));
           break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
           $command = call_user_func_array(
             'csprintf',
             array_merge(
               array(
                 "(ssh-add %s && git {$pattern})",
                 $this->getSSHKeyfile(),
               ),
               $args));
           $pattern = "ssh-agent sh -c %s";
           $args = array($command);
           break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
           $pattern = "hg --config ui.ssh=%s {$pattern}";
           array_unshift(
             $args,
             csprintf(
               'ssh -l %s -i %s',
               $this->getSSHLogin(),
               $this->getSSHKeyfile()));
           break;
         default:
           throw new Exception("Unrecognized version control system.");
       }
     } else if ($this->shouldUseHTTP()) {
       switch ($this->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
           $pattern =
             "svn ".
             "--non-interactive ".
             "--no-auth-cache ".
             "--trust-server-cert ".
             "--username %s ".
             "--password %s ".
             $pattern;
           array_unshift(
             $args,
             $this->getDetail('http-login'),
             $this->getDetail('http-pass'));
           break;
         default:
           throw new Exception(
             "No support for HTTP Basic Auth in this version control system.");
       }
     } else if ($this->shouldUseSVNProtocol()) {
       switch ($this->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
             $pattern =
               "svn ".
               "--non-interactive ".
               "--no-auth-cache ".
               "--username %s ".
               "--password %s ".
               $pattern;
             array_unshift(
               $args,
               $this->getDetail('http-login'),
               $this->getDetail('http-pass'));
             break;
         default:
           throw new Exception(
             "SVN protocol is SVN only.");
       }
     } else {
       switch ($this->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
           $pattern = "svn --non-interactive {$pattern}";
           break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
           $pattern = "git {$pattern}";
           break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
           $pattern = "hg {$pattern}";
           break;
         default:
           throw new Exception("Unrecognized version control system.");
       }
     }
 
     array_unshift($args, $pattern);
 
     return $args;
   }
 
   private function formatLocalCommand(array $args) {
     $pattern = $args[0];
     $args = array_slice($args, 1);
 
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         $pattern = "(cd %s && svn --non-interactive {$pattern})";
         array_unshift($args, $this->getLocalPath());
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         $pattern = "(cd %s && git {$pattern})";
         array_unshift($args, $this->getLocalPath());
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         $pattern = "(cd %s && HGPLAIN=1 hg {$pattern})";
         array_unshift($args, $this->getLocalPath());
         break;
       default:
         throw new Exception("Unrecognized version control system.");
     }
 
     array_unshift($args, $pattern);
 
     return $args;
   }
 
   private function getSSHLogin() {
     return $this->getDetail('ssh-login');
   }
 
   private function getSSHKeyfile() {
     if ($this->sshKeyfile === null) {
       $key = $this->getDetail('ssh-key');
       $keyfile = $this->getDetail('ssh-keyfile');
       if ($keyfile) {
         // Make sure we can read the file, that it exists, etc.
         Filesystem::readFile($keyfile);
         $this->sshKeyfile = $keyfile;
       } else if ($key) {
         $keyfile = new TempFile('phabricator-repository-ssh-key');
         chmod($keyfile, 0600);
         Filesystem::writeFile($keyfile, $key);
         $this->sshKeyfile = $keyfile;
       } else {
         $this->sshKeyfile = '';
       }
     }
 
     return (string)$this->sshKeyfile;
   }
 
   public function getURI() {
     return '/diffusion/'.$this->getCallsign().'/';
   }
 
   public function isTracked() {
     return $this->getDetail('tracking-enabled', false);
   }
 
   public function getDefaultBranch() {
     $default = $this->getDetail('default-branch');
     if (strlen($default)) {
       return $default;
     }
 
     $default_branches = array(
       PhabricatorRepositoryType::REPOSITORY_TYPE_GIT        => 'master',
       PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL  => 'default',
     );
 
     return idx($default_branches, $this->getVersionControlSystem());
   }
 
+  public function getDefaultArcanistBranch() {
+    return coalesce($this->getDefaultBranch(), 'svn');
+  }
+
   private function isBranchInFilter($branch, $filter_key) {
     $vcs = $this->getVersionControlSystem();
 
     $is_git = ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT);
 
     $use_filter = ($is_git);
 
     if ($use_filter) {
       $filter = $this->getDetail($filter_key, array());
       if ($filter && empty($filter[$branch])) {
         return false;
       }
     }
 
     // By default, all branches pass.
     return true;
   }
 
   public function shouldTrackBranch($branch) {
     return $this->isBranchInFilter($branch, 'branch-filter');
   }
 
   public function shouldAutocloseBranch($branch) {
     if ($this->getDetail('disable-autoclose', false)) {
       return false;
     }
 
     return $this->isBranchInFilter($branch, 'close-commits-filter');
   }
 
   public function shouldAutocloseCommit(
     PhabricatorRepositoryCommit $commit,
     PhabricatorRepositoryCommitData $data) {
 
     if ($this->getDetail('disable-autoclose', false)) {
       return false;
     }
 
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         return true;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         return true;
       default:
         throw new Exception("Unrecognized version control system.");
     }
 
     $branches = $data->getCommitDetail('seenOnBranches', array());
     foreach ($branches as $branch) {
       if ($this->shouldAutocloseBranch($branch)) {
         return true;
       }
     }
 
     return false;
   }
 
   public function formatCommitName($commit_identifier) {
     $vcs = $this->getVersionControlSystem();
 
     $type_git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
     $type_hg = PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL;
 
     $is_git = ($vcs == $type_git);
     $is_hg = ($vcs == $type_hg);
     if ($is_git || $is_hg) {
       $short_identifier = substr($commit_identifier, 0, 12);
     } else {
       $short_identifier = $commit_identifier;
     }
 
     return 'r'.$this->getCallsign().$short_identifier;
   }
 
   public static function loadAllByPHIDOrCallsign(array $names) {
     $repositories = array();
     foreach ($names as $name) {
       $repo = id(new PhabricatorRepository())->loadOneWhere(
         'phid = %s OR callsign = %s',
         $name,
         $name);
       if (!$repo) {
         throw new Exception(
           "No repository with PHID or callsign '{$name}' exists!");
       }
       $repositories[$repo->getID()] = $repo;
     }
     return $repositories;
   }
 
 /* -(  Repository URI Management  )------------------------------------------ */
 
 
   /**
    * Get the remote URI for this repository.
    *
    * @return string
    * @task uri
    */
   public function getRemoteURI() {
     return (string)$this->getRemoteURIObject();
   }
 
 
   /**
    * Get the remote URI for this repository, without authentication information.
    *
    * @return string Repository URI.
    * @task uri
    */
   public function getPublicRemoteURI() {
     $uri = $this->getRemoteURIObject();
 
     // Make sure we don't leak anything if this repo is using HTTP Basic Auth
     // with the credentials in the URI or something zany like that.
 
     if ($uri instanceof PhutilGitURI) {
       $uri->setUser(null);
     } else {
       $uri->setUser(null);
       $uri->setPass(null);
     }
 
     return (string)$uri;
   }
 
 
   /**
    * Get the protocol for the repository's remote.
    *
    * @return string Protocol, like "ssh" or "git".
    * @task uri
    */
   public function getRemoteProtocol() {
     $uri = $this->getRemoteURIObject();
 
     if ($uri instanceof PhutilGitURI) {
       return 'ssh';
     } else {
       return $uri->getProtocol();
     }
   }
 
 
   /**
    * Get a parsed object representation of the repository's remote URI. This
    * may be a normal URI (returned as a @{class@libphutil:PhutilURI}) or a git
    * URI (returned as a @{class@libphutil:PhutilGitURI}).
    *
    * @return wild A @{class@libphutil:PhutilURI} or
    *              @{class@libphutil:PhutilGitURI}.
    * @task uri
    */
   private function getRemoteURIObject() {
     $raw_uri = $this->getDetail('remote-uri');
     if (!$raw_uri) {
       return new PhutilURI('');
     }
 
     if (!strncmp($raw_uri, '/', 1)) {
       return new PhutilURI('file://'.$raw_uri);
     }
 
     $uri = new PhutilURI($raw_uri);
     if ($uri->getProtocol()) {
       if ($this->isSSHProtocol($uri->getProtocol())) {
         if ($this->getSSHLogin()) {
           $uri->setUser($this->getSSHLogin());
         }
       }
       return $uri;
     }
 
     $uri = new PhutilGitURI($raw_uri);
     if ($uri->getDomain()) {
       if ($this->getSSHLogin()) {
         $uri->setUser($this->getSSHLogin());
       }
       return $uri;
     }
 
     throw new Exception("Remote URI '{$raw_uri}' could not be parsed!");
   }
 
 
   /**
    * Determine if we should connect to the remote using SSH flags and
    * credentials.
    *
    * @return bool True to use the SSH protocol.
    * @task uri
    */
   private function shouldUseSSH() {
     $protocol = $this->getRemoteProtocol();
     if ($this->isSSHProtocol($protocol)) {
       return (bool)$this->getSSHKeyfile();
     } else {
       return false;
     }
   }
 
 
   /**
    * Determine if we should connect to the remote using HTTP flags and
    * credentials.
    *
    * @return bool True to use the HTTP protocol.
    * @task uri
    */
   private function shouldUseHTTP() {
     $protocol = $this->getRemoteProtocol();
     if ($protocol == 'http' || $protocol == 'https') {
       return (bool)$this->getDetail('http-login');
     } else {
       return false;
     }
   }
 
 
   /**
    * Determine if we should connect to the remote using SVN flags and
    * credentials.
    *
    * @return bool True to use the SVN protocol.
    * @task uri
    */
   private function shouldUseSVNProtocol() {
     $protocol = $this->getRemoteProtocol();
     if ($protocol == 'svn') {
       return (bool)$this->getDetail('http-login');
     } else {
       return false;
     }
   }
 
 
   /**
    * Determine if a protocol is SSH or SSH-like.
    *
    * @param string A protocol string, like "http" or "ssh".
    * @return bool True if the protocol is SSH-like.
    * @task uri
    */
   private function isSSHProtocol($protocol) {
     return ($protocol == 'ssh' || $protocol == 'svn+ssh');
   }
 
   public function delete() {
     $this->openTransaction();
 
       $paths = id(new PhabricatorOwnersPath())
         ->loadAllWhere('repositoryPHID = %s', $this->getPHID());
       foreach ($paths as $path) {
         $path->delete();
       }
 
       $projects = id(new PhabricatorRepositoryArcanistProject())
         ->loadAllWhere('repositoryID = %d', $this->getID());
       foreach ($projects as $project) {
         // note each project deletes its PhabricatorRepositorySymbols
         $project->delete();
       }
 
       $commits = id(new PhabricatorRepositoryCommit())
         ->loadAllWhere('repositoryID = %d', $this->getID());
       foreach ($commits as $commit) {
         // note PhabricatorRepositoryAuditRequests and
         // PhabricatorRepositoryCommitData are deleted here too.
         $commit->delete();
       }
 
       $conn_w = $this->establishConnection('w');
 
       queryfx(
         $conn_w,
         'DELETE FROM %T WHERE repositoryID = %d',
         self::TABLE_FILESYSTEM,
         $this->getID());
 
       queryfx(
         $conn_w,
         'DELETE FROM %T WHERE repositoryID = %d',
         self::TABLE_PATHCHANGE,
         $this->getID());
 
       queryfx(
         $conn_w,
         'DELETE FROM %T WHERE repositoryID = %d',
         self::TABLE_SUMMARY,
         $this->getID());
 
       $result = parent::delete();
 
     $this->saveTransaction();
     return $result;
   }
 }