Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diffusion/conduit/DiffusionMergedCommitsQueryConduitAPIMethod.php
12242 views
1
<?php
2
3
final class DiffusionMergedCommitsQueryConduitAPIMethod
4
extends DiffusionQueryConduitAPIMethod {
5
6
public function getAPIMethodName() {
7
return 'diffusion.mergedcommitsquery';
8
}
9
10
public function getMethodDescription() {
11
return pht(
12
'Merged commit information for a specific commit in a repository.');
13
}
14
15
protected function defineReturnType() {
16
return 'array';
17
}
18
19
protected function defineCustomParamTypes() {
20
return array(
21
'commit' => 'required string',
22
'limit' => 'optional int',
23
);
24
}
25
26
private function getLimit(ConduitAPIRequest $request) {
27
// TODO: Paginate this sensibly at some point.
28
return $request->getValue('limit', 4096);
29
}
30
31
protected function getGitResult(ConduitAPIRequest $request) {
32
$drequest = $this->getDiffusionRequest();
33
$repository = $drequest->getRepository();
34
$commit = $request->getValue('commit');
35
$limit = $this->getLimit($request);
36
37
list($parents) = $repository->execxLocalCommand(
38
'log -n 1 %s %s --',
39
'--format=%P',
40
gitsprintf('%s', $commit));
41
42
$parents = preg_split('/\s+/', trim($parents));
43
if (count($parents) < 2) {
44
// This is not a merge commit, so it doesn't merge anything.
45
return array();
46
}
47
48
// Get all of the commits which are not reachable from the first parent.
49
// These are the commits this change merges.
50
51
$first_parent = head($parents);
52
list($logs) = $repository->execxLocalCommand(
53
'log -n %d %s %s %s --',
54
// NOTE: "+ 1" accounts for the merge commit itself.
55
$limit + 1,
56
'--format=%H',
57
gitsprintf('%s', $commit),
58
gitsprintf('%s', '^'.$first_parent));
59
60
$hashes = explode("\n", trim($logs));
61
62
// Remove the merge commit.
63
$hashes = array_diff($hashes, array($commit));
64
65
$history = DiffusionQuery::loadHistoryForCommitIdentifiers(
66
$hashes,
67
$drequest);
68
return mpull($history, 'toDictionary');
69
}
70
71
protected function getMercurialResult(ConduitAPIRequest $request) {
72
$drequest = $this->getDiffusionRequest();
73
$repository = $drequest->getRepository();
74
$commit = $request->getValue('commit');
75
$limit = $this->getLimit($request);
76
77
list($parents) = $repository->execxLocalCommand(
78
'parents --template=%s --rev %s',
79
'{node}\\n',
80
hgsprintf('%s', $commit));
81
$parents = explode("\n", trim($parents));
82
83
if (count($parents) < 2) {
84
// Not a merge commit.
85
return array();
86
}
87
88
// NOTE: In Git, the first parent is the "mainline". In Mercurial, the
89
// second parent is the "mainline" (the way 'git merge' and 'hg merge'
90
// work is also reversed).
91
92
$last_parent = last($parents);
93
list($logs) = $repository->execxLocalCommand(
94
'log --template=%s --follow --limit %d --rev %s:0 --prune %s --',
95
'{node}\\n',
96
$limit + 1,
97
$commit,
98
$last_parent);
99
100
$hashes = explode("\n", trim($logs));
101
102
// Remove the merge commit.
103
$hashes = array_diff($hashes, array($commit));
104
105
$history = DiffusionQuery::loadHistoryForCommitIdentifiers(
106
$hashes,
107
$drequest);
108
return mpull($history, 'toDictionary');
109
}
110
111
}
112
113