1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-01 11:12:42 +01:00
phorge-phorge/src/applications/diffusion/conduit/DiffusionMergedCommitsQueryConduitAPIMethod.php

111 lines
3 KiB
PHP
Raw Normal View History

<?php
final class DiffusionMergedCommitsQueryConduitAPIMethod
extends DiffusionQueryConduitAPIMethod {
public function getAPIMethodName() {
return 'diffusion.mergedcommitsquery';
}
public function getMethodDescription() {
return
'Merged commit information for a specific commit in a repository.';
}
protected function defineReturnType() {
return 'array';
}
protected function defineCustomParamTypes() {
return array(
'commit' => 'required string',
'limit' => 'optional int',
);
}
private function getLimit(ConduitAPIRequest $request) {
return $request->getValue('limit', PHP_INT_MAX);
}
protected function getGitResult(ConduitAPIRequest $request) {
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
$commit = $request->getValue('commit');
$limit = $this->getLimit($request);
list($parents) = $repository->execxLocalCommand(
'log -n 1 --format=%s %s',
'%P',
$commit);
$parents = preg_split('/\s+/', trim($parents));
if (count($parents) < 2) {
// This is not a merge commit, so it doesn't merge anything.
return array();
}
// Get all of the commits which are not reachable from the first parent.
// These are the commits this change merges.
$first_parent = head($parents);
list($logs) = $repository->execxLocalCommand(
'log -n %d --format=%s %s %s --',
// NOTE: "+ 1" accounts for the merge commit itself.
$limit + 1,
'%H',
$commit,
'^'.$first_parent);
$hashes = explode("\n", trim($logs));
// Remove the merge commit.
$hashes = array_diff($hashes, array($commit));
$history = DiffusionQuery::loadHistoryForCommitIdentifiers(
$hashes,
$drequest);
return mpull($history, 'toDictionary');
}
protected function getMercurialResult(ConduitAPIRequest $request) {
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
$commit = $request->getValue('commit');
$limit = $this->getLimit($request);
list($parents) = $repository->execxLocalCommand(
'parents --template=%s --rev %s',
'{node}\\n',
$commit);
$parents = explode("\n", trim($parents));
if (count($parents) < 2) {
// Not a merge commit.
return array();
}
// NOTE: In Git, the first parent is the "mainline". In Mercurial, the
// second parent is the "mainline" (the way 'git merge' and 'hg merge'
// work is also reversed).
$last_parent = last($parents);
list($logs) = $repository->execxLocalCommand(
'log --template=%s --follow --limit %d --rev %s:0 --prune %s --',
'{node}\\n',
$limit + 1,
$commit,
$last_parent);
$hashes = explode("\n", trim($logs));
// Remove the merge commit.
$hashes = array_diff($hashes, array($commit));
$history = DiffusionQuery::loadHistoryForCommitIdentifiers(
$hashes,
$drequest);
return mpull($history, 'toDictionary');
}
}