From 7d615a97e24054bf7cb3509fc4da7d3217dd8905 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 5 Jun 2020 12:55:55 -0700 Subject: [PATCH] In "arc branch" output, sort branches updated in the same second by name Summary: Ref T13546. The new "arc land" workflow can rebase several branches per second. With branches like "feature1", "feature2", etc., this leads to out-of-order listing in "arc branch". When two branches would otherwise sort to the same position, sort them by name. Test Plan: Ran "arc branch" after a cascading rebase by "arc land", saw "land5", "land7", "land8", etc., instead of an arbitrary order. Maniphest Tasks: T13546 Differential Revision: https://secure.phabricator.com/D21316 --- src/workflow/ArcanistFeatureBaseWorkflow.php | 31 ++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/workflow/ArcanistFeatureBaseWorkflow.php b/src/workflow/ArcanistFeatureBaseWorkflow.php index 94756c2a..b6224d34 100644 --- a/src/workflow/ArcanistFeatureBaseWorkflow.php +++ b/src/workflow/ArcanistFeatureBaseWorkflow.php @@ -201,7 +201,13 @@ EOHELP $epoch = $commit->getCommitEpoch(); $color = idx($color_map, $status, 'default'); - $ssort = sprintf('%d%012d', idx($ssort_map, $status, 0), $epoch); + + $epoch_vector = id(new PhutilSortVector()) + ->addInt($epoch); + + $status_vector = id(new PhutilSortVector()) + ->addInt(idx($ssort_map, $status, 0)) + ->addInt($epoch); if ($revision) { $desc = $revision->getFullName(); @@ -216,9 +222,10 @@ EOHELP 'desc' => $desc, 'revision' => $revision ? $revision->getID() : null, 'color' => $color, - 'esort' => $epoch, 'epoch' => $epoch, - 'ssort' => $ssort, + + 'esort' => $epoch_vector, + 'ssort' => $status_vector, ); } @@ -230,11 +237,25 @@ EOHELP $len_name = max(array_map('strlen', ipull($out, 'name'))) + 2; $len_status = max(array_map('strlen', ipull($out, 'status'))) + 2; + // Sort the list in natural order first. When we apply a stable sort to + // the list below, branches which were last updated at the same time will + // retain this ordering. This allows "feature1", "feature2", etc., to + // display in the correct order if they were touched at the same second, + // which is common when "arc land" performs a cascading rebase. + + $name_map = ipull($out, 'name'); + natcasesort($name_map); + $out = array_select_keys($out, array_keys($name_map)); + if ($this->getArgument('by-status')) { - $out = isort($out, 'ssort'); + $vectors = ipull($out, 'ssort'); } else { - $out = isort($out, 'esort'); + $vectors = ipull($out, 'esort'); } + + $vectors = msortv($vectors, 'getSelf'); + $out = array_select_keys($out, array_keys($vectors)); + if ($this->getArgument('output') == 'json') { foreach ($out as &$feature) { unset($feature['color'], $feature['ssort'], $feature['esort']);