diff --git a/src/applications/diffusion/controller/DiffusionBranchTableController.php b/src/applications/diffusion/controller/DiffusionBranchTableController.php index 65d7b8fd13..13f566a57b 100644 --- a/src/applications/diffusion/controller/DiffusionBranchTableController.php +++ b/src/applications/diffusion/controller/DiffusionBranchTableController.php @@ -1,100 +1,140 @@ loadDiffusionContext(); if ($response) { return $response; } $viewer = $this->getViewer(); $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); $pager = id(new PHUIPagerView()) ->readFromRequest($request); $params = array( 'offset' => $pager->getOffset(), 'limit' => $pager->getPageSize() + 1, 'branch' => null, ); $contains = $drequest->getSymbolicCommit(); if (strlen($contains)) { $params['contains'] = $contains; } $branches = $this->callConduitWithDiffusionRequest( 'diffusion.branchquery', $params); $branches = $pager->sliceResults($branches); $branches = DiffusionRepositoryRef::loadAllFromDictionaries($branches); + // If there is one page of results or fewer, sort branches so the default + // branch is on top and permanent branches are below it. + if (!$pager->getOffset() && !$pager->getHasMorePages()) { + $branches = $this->sortBranches($repository, $branches); + } + $content = null; if (!$branches) { $content = $this->renderStatusMessage( pht('No Branches'), pht('This repository has no branches.')); } else { $commits = id(new DiffusionCommitQuery()) ->setViewer($viewer) ->withIdentifiers(mpull($branches, 'getCommitIdentifier')) ->withRepository($repository) ->execute(); $list = id(new DiffusionBranchListView()) ->setUser($viewer) ->setBranches($branches) ->setCommits($commits) ->setDiffusionRequest($drequest); $content = id(new PHUIObjectBoxView()) ->setHeaderText($repository->getName()) ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->addClass('diffusion-mobile-view') ->setTable($list) ->setPager($pager); } $crumbs = $this->buildCrumbs( array( 'branches' => true, )); $crumbs->setBorder(true); $header = id(new PHUIHeaderView()) ->setHeader(pht('Branches')) ->setHeaderIcon('fa-code-fork'); if (!$repository->isSVN()) { $branch_tag = $this->renderBranchTag($drequest); $header->addTag($branch_tag); } $tabs = $this->buildTabsView('branch'); $view = id(new PHUITwoColumnView()) ->setHeader($header) ->setTabs($tabs) ->setFooter(array( $content, )); return $this->newPage() ->setTitle( array( pht('Branches'), $repository->getDisplayName(), )) ->setCrumbs($crumbs) ->appendChild($view); } + private function sortBranches( + PhabricatorRepository $repository, + array $branches) { + + $publisher = $repository->newPublisher(); + $default_branch = $repository->getDefaultBranch(); + + $vectors = array(); + foreach ($branches as $key => $branch) { + $short_name = $branch->getShortName(); + + if ($short_name === $default_branch) { + $order_default = 0; + } else { + $order_default = 1; + } + + if ($publisher->shouldPublishRef($branch)) { + $order_permanent = 0; + } else { + $order_permanent = 1; + } + + $vectors[$key] = id(new PhutilSortVector()) + ->addInt($order_default) + ->addInt($order_permanent) + ->addString($short_name); + } + + $vectors = msortv($vectors, 'getSelf'); + + return array_select_keys($branches, array_keys($vectors)); + } + } diff --git a/src/applications/diffusion/view/DiffusionBranchListView.php b/src/applications/diffusion/view/DiffusionBranchListView.php index 73ad87041a..c0985858f8 100644 --- a/src/applications/diffusion/view/DiffusionBranchListView.php +++ b/src/applications/diffusion/view/DiffusionBranchListView.php @@ -1,141 +1,150 @@ branches = $branches; return $this; } public function setCommits(array $commits) { assert_instances_of($commits, 'PhabricatorRepositoryCommit'); $this->commits = mpull($commits, null, 'getCommitIdentifier'); return $this; } public function render() { $drequest = $this->getDiffusionRequest(); $current_branch = $drequest->getBranch(); $repository = $drequest->getRepository(); $commits = $this->commits; $viewer = $this->getUser(); require_celerity_resource('diffusion-css'); $buildables = $this->loadBuildables($commits); $have_builds = false; $can_close_branches = ($repository->isHg()); Javelin::initBehavior('phabricator-tooltips'); $list = id(new PHUIObjectItemListView()) - ->setFlush(true) ->addClass('diffusion-history-list') ->addClass('diffusion-branch-list'); + $publisher = $repository->newPublisher(); + foreach ($this->branches as $branch) { $build_view = null; $button_bar = new PHUIButtonBarView(); $commit = idx($commits, $branch->getCommitIdentifier()); if ($commit) { $details = $commit->getSummary(); $datetime = phabricator_datetime($commit->getEpoch(), $viewer); $buildable = idx($buildables, $commit->getPHID()); if ($buildable) { $build_view = $this->renderBuildable($buildable, 'button'); } } else { $datetime = null; $details = null; } if ($repository->supportsBranchComparison()) { $compare_uri = $drequest->generateURI( array( 'action' => 'compare', 'head' => $branch->getShortName(), )); $can_compare = ($branch->getShortName() != $current_branch); if ($can_compare) { $button_bar->addButton( id(new PHUIButtonView()) ->setTag('a') ->setIcon('fa-balance-scale') ->setToolTip(pht('Compare')) ->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE) ->setWorkflow(true) ->setHref($compare_uri)); } } $browse_href = $drequest->generateURI( array( 'action' => 'browse', 'branch' => $branch->getShortName(), )); $button_bar->addButton( id(new PHUIButtonView()) ->setIcon('fa-code') ->setHref($browse_href) ->setTag('a') ->setTooltip(pht('Browse')) ->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE)); $commit_link = $repository->getCommitURI( $branch->getCommitIdentifier()); $commit_name = $repository->formatCommitName( $branch->getCommitIdentifier(), $local = true); $commit_tag = id(new PHUITagView()) ->setName($commit_name) ->setHref($commit_link) ->setType(PHUITagView::TYPE_SHADE) ->setColor(PHUITagView::COLOR_INDIGO) ->setBorder(PHUITagView::BORDER_NONE) ->setSlimShady(true); $subhead = array($commit_tag, ' ', $details); $item = id(new PHUIObjectItemView()) ->setHeader($branch->getShortName()) ->setHref($drequest->generateURI( array( 'action' => 'history', 'branch' => $branch->getShortName(), ))) ->setSubhead($subhead) ->setSideColumn(array( $build_view, $button_bar, )); if ($branch->getShortName() == $repository->getDefaultBranch()) { - $item->setStatusIcon('fa-code-fork', pht('Default Branch')); + $item->setStatusIcon('fa-star', pht('Default Branch')); + } else { + if ($publisher->shouldPublishRef($branch)) { + $item->setStatusIcon('fa-code-fork', pht('Permanent Ref')); + } else { + $item->setStatusIcon( + 'fa-folder-open-o grey', pht('Not a Permanent Ref')); + } } + $item->addAttribute(array($datetime)); if ($can_close_branches) { $fields = $branch->getRawFields(); $closed = idx($fields, 'closed'); if ($closed) { $status = pht('Branch Closed'); $item->setDisabled(true); } else { $status = pht('Branch Open'); } $item->addAttribute($status); } $list->addItem($item); } return $list; } }