Skip to content

Commit 35ccda9

Browse files
author
epriestley
committed
Merge diffusion.commitbranchesquery into diffusion.branchquery
Summary: Ref T4327. This is general cleanup since I was in this area of the code. Primarily, the Mercurial implementation here was completely broken and wrong: - It returned only one branch, but a commit can be present on many branches. - It did not account for multiple branch heads. - It returned a result implying the branch head pointed at the queried commit, which is no consistent or accurate. Simplify the amount of API we're dealing with by collapsing this method into the very similar `diffusion.branchquery` method. Test Plan: Looked at mercurial and git repositories and commits, branch information seemed correct. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T4327 Differential Revision: https://secure.phabricator.com/D8003
1 parent 4c26961 commit 35ccda9

4 files changed

+75
-84
lines changed

src/__phutil_library_map__.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@
155155
'ConduitAPI_diffusion_abstractquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_abstractquery_Method.php',
156156
'ConduitAPI_diffusion_branchquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_branchquery_Method.php',
157157
'ConduitAPI_diffusion_browsequery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_browsequery_Method.php',
158-
'ConduitAPI_diffusion_commitbranchesquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_commitbranchesquery_Method.php',
159158
'ConduitAPI_diffusion_commitparentsquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_commitparentsquery_Method.php',
160159
'ConduitAPI_diffusion_createcomment_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_createcomment_Method.php',
161160
'ConduitAPI_diffusion_diffquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_diffquery_Method.php',
@@ -2615,7 +2614,6 @@
26152614
'ConduitAPI_diffusion_abstractquery_Method' => 'ConduitAPI_diffusion_Method',
26162615
'ConduitAPI_diffusion_branchquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
26172616
'ConduitAPI_diffusion_browsequery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
2618-
'ConduitAPI_diffusion_commitbranchesquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
26192617
'ConduitAPI_diffusion_commitparentsquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',
26202618
'ConduitAPI_diffusion_createcomment_Method' => 'ConduitAPI_diffusion_Method',
26212619
'ConduitAPI_diffusion_diffquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method',

src/applications/diffusion/conduit/ConduitAPI_diffusion_branchquery_Method.php

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,59 @@
11
<?php
22

3-
/**
4-
* @group conduit
5-
*/
63
final class ConduitAPI_diffusion_branchquery_Method
74
extends ConduitAPI_diffusion_abstractquery_Method {
85

96
public function getMethodDescription() {
10-
return 'Determine what branches exist for a repository.';
7+
return pht('Determine what branches exist for a repository.');
118
}
129

1310
public function defineReturnType() {
14-
return 'array';
11+
return 'list<dict>';
1512
}
1613

1714
protected function defineCustomParamTypes() {
1815
return array(
1916
'limit' => 'optional int',
20-
'offset' => 'optional int'
17+
'offset' => 'optional int',
18+
'contains' => 'optional string',
2119
);
2220
}
2321

24-
2522
protected function getGitResult(ConduitAPIRequest $request) {
2623
$drequest = $this->getDiffusionRequest();
2724
$repository = $drequest->getRepository();
2825

29-
$refs = id(new DiffusionLowLevelGitRefQuery())
30-
->setRepository($repository)
31-
->withIsOriginBranch(true)
32-
->execute();
26+
$contains = $request->getValue('contains');
27+
if (strlen($contains)) {
28+
// NOTE: We can't use DiffusionLowLevelGitRefQuery here because
29+
// `git for-each-ref` does not support `--contains`.
30+
if ($repository->isWorkingCopyBare()) {
31+
list($stdout) = $repository->execxLocalCommand(
32+
'branch --verbose --no-abbrev --contains %s --',
33+
$contains);
34+
$ref_map = DiffusionGitBranch::parseLocalBranchOutput(
35+
$stdout);
36+
} else {
37+
list($stdout) = $repository->execxLocalCommand(
38+
'branch -r --verbose --no-abbrev --contains %s --',
39+
$contains);
40+
$ref_map = DiffusionGitBranch::parseRemoteBranchOutput(
41+
$stdout,
42+
DiffusionGitBranch::DEFAULT_GIT_REMOTE);
43+
}
44+
45+
$refs = array();
46+
foreach ($ref_map as $ref => $commit) {
47+
$refs[] = id(new DiffusionRepositoryRef())
48+
->setShortName($ref)
49+
->setCommitIdentifier($commit);
50+
}
51+
} else {
52+
$refs = id(new DiffusionLowLevelGitRefQuery())
53+
->setRepository($repository)
54+
->withIsOriginBranch(true)
55+
->execute();
56+
}
3357

3458
return $this->processBranchRefs($request, $refs);
3559
}
@@ -42,6 +66,37 @@ protected function getMercurialResult(ConduitAPIRequest $request) {
4266
->setRepository($repository)
4367
->execute();
4468

69+
// If we have a 'contains' query, filter these branches down to just the
70+
// ones which contain the commit.
71+
$contains = $request->getValue('contains');
72+
if (strlen($contains)) {
73+
list($branches_raw) = $repository->execxLocalCommand(
74+
'log --template %s --limit 1 --rev %s --',
75+
'{branches}',
76+
hgsprintf('%s', $contains));
77+
78+
$branches_raw = trim($branches_raw);
79+
if (!strlen($branches_raw)) {
80+
$containing_branches = array('default');
81+
} else {
82+
$containing_branches = explode(' ', $branches_raw);
83+
}
84+
85+
$containing_branches = array_fuse($containing_branches);
86+
87+
// NOTE: We get this very slightly wrong: a branch may have multiple
88+
// heads and we'll keep all of the heads of the branch, even if the
89+
// commit is only on some of the heads. This should be rare, is probably
90+
// more clear to users as is, and would potentially be expensive to get
91+
// right since we'd have to do additional checks.
92+
93+
foreach ($refs as $key => $ref) {
94+
if (empty($containing_branches[$ref->getShortName()])) {
95+
unset($refs[$key]);
96+
}
97+
}
98+
}
99+
45100
return $this->processBranchRefs($request, $refs);
46101
}
47102

src/applications/diffusion/conduit/ConduitAPI_diffusion_commitbranchesquery_Method.php

Lines changed: 0 additions & 66 deletions
This file was deleted.

src/applications/diffusion/controller/DiffusionCommitBranchesController.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,30 @@ public function processRequest() {
1717
$branches = array();
1818
try {
1919
$branches = $this->callConduitWithDiffusionRequest(
20-
'diffusion.commitbranchesquery',
21-
array('commit' => $request->getCommit()));
20+
'diffusion.branchquery',
21+
array(
22+
'contains' => $request->getCommit(),
23+
));
2224
} catch (ConduitException $ex) {
2325
if ($ex->getMessage() != 'ERR-UNSUPPORTED-VCS') {
2426
throw $ex;
2527
}
2628
}
2729

30+
$branches = DiffusionRepositoryRef::loadAllFromDictionaries($branches);
31+
2832
$branch_links = array();
29-
foreach ($branches as $branch => $commit) {
33+
foreach ($branches as $branch) {
3034
$branch_links[] = phutil_tag(
3135
'a',
3236
array(
3337
'href' => $request->generateURI(
3438
array(
3539
'action' => 'browse',
36-
'branch' => $branch,
40+
'branch' => $branch->getShortName(),
3741
)),
3842
),
39-
$branch);
43+
$branch->getShortName());
4044
}
4145

4246
return id(new AphrontAjaxResponse())

0 commit comments

Comments
 (0)