@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3/**
4 * Execute and parse a low-level Mercurial branches query using `hg branches`.
5 */
6final class DiffusionLowLevelMercurialBranchesQuery
7 extends DiffusionLowLevelQuery {
8
9 private $contains;
10
11 public function withContainsCommit($commit) {
12 $this->contains = $commit;
13 return $this;
14 }
15
16 protected function executeQuery() {
17 $repository = $this->getRepository();
18
19 $specs = array();
20 if ($this->contains !== null) {
21 $specs['all'] = hgsprintf(
22 '(descendants(%s) and head())',
23 $this->contains);
24 $specs['open'] = hgsprintf(
25 '(descendants(%s) and head() and not closed())',
26 $this->contains);
27 } else {
28 $specs['all'] = hgsprintf('head()');
29 $specs['open'] = hgsprintf('head() and not closed()');
30 }
31
32 $futures = array();
33 foreach ($specs as $key => $spec) {
34 $futures[$key] = $repository->getLocalCommandFuture(
35 'log --template %s --rev %s',
36 '{node}\1{branch}\2',
37 $spec);
38 }
39
40 $branches = array();
41 $open = array();
42 foreach (new FutureIterator($futures) as $key => $future) {
43 list($stdout) = $future->resolvex();
44
45 $lines = explode("\2", $stdout);
46 $lines = array_filter($lines);
47 foreach ($lines as $line) {
48 list($node, $branch) = explode("\1", $line);
49 $id = $node.'/'.$branch;
50 if (empty($branches[$id])) {
51 $branches[$id] = id(new DiffusionRepositoryRef())
52 ->setShortName($branch)
53 ->setCommitIdentifier($node);
54 }
55
56 if ($key == 'open') {
57 $open[$id] = true;
58 }
59 }
60 }
61
62 foreach ($branches as $id => $branch) {
63 $branch->setRawFields(
64 array(
65 'closed' => (empty($open[$id])),
66 ));
67 }
68
69 return array_values($branches);
70 }
71
72}