mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
8982e3e52d
Summary: Ref T11823. This is the meaty part of the change, and updates `RefEngine` to use separate RefCursor (for names) and RefPosition (for actual commit positions) tables. I'll hold this whole series until after the release cut so it has some time to bake on `secure` to look for issues. It's also not a huge problem if there are bugs here since these tables are just caches anyway, although they do feed into some other things, and obviously it's never good to have bugs. Test Plan: - This logic can be invoked directly with `bin/repository refs <repository> --trace --verbose`. - Ran that on unchanged repositories, new branches, removed branches, and modified branches. Saw appropriate output and cursor positions. - Ran on a mercurial repository to test the close/open logic, saw it correct open/closed state of incorrect positions. - Browed around Diffusion in various repositories. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T11823 Differential Revision: https://secure.phabricator.com/D18614
157 lines
4.3 KiB
PHP
157 lines
4.3 KiB
PHP
<?php
|
|
|
|
final class DifferentialRevisionOperationController
|
|
extends DifferentialController {
|
|
|
|
public function handleRequest(AphrontRequest $request) {
|
|
$viewer = $this->getViewer();
|
|
$id = $request->getURIData('id');
|
|
|
|
$revision = id(new DifferentialRevisionQuery())
|
|
->withIDs(array($id))
|
|
->setViewer($viewer)
|
|
->needActiveDiffs(true)
|
|
->executeOne();
|
|
if (!$revision) {
|
|
return new Aphront404Response();
|
|
}
|
|
|
|
$detail_uri = "/D{$id}";
|
|
|
|
$op = new DrydockLandRepositoryOperation();
|
|
$barrier = $op->getBarrierToLanding($viewer, $revision);
|
|
if ($barrier) {
|
|
return $this->newDialog()
|
|
->setTitle($barrier['title'])
|
|
->appendParagraph($barrier['body'])
|
|
->addCancelButton($detail_uri);
|
|
}
|
|
|
|
$diff = $revision->getActiveDiff();
|
|
$repository = $revision->getRepository();
|
|
|
|
$default_ref = $this->loadDefaultRef($repository, $diff);
|
|
|
|
if ($default_ref) {
|
|
$v_ref = array($default_ref->getPHID());
|
|
} else {
|
|
$v_ref = array();
|
|
}
|
|
|
|
$e_ref = true;
|
|
|
|
$errors = array();
|
|
if ($request->isFormPost()) {
|
|
|
|
$v_ref = $request->getArr('refPHIDs');
|
|
$ref_phid = head($v_ref);
|
|
if (!strlen($ref_phid)) {
|
|
$e_ref = pht('Required');
|
|
$errors[] = pht(
|
|
'You must select a branch to land this revision onto.');
|
|
} else {
|
|
$ref = $this->newRefQuery($repository)
|
|
->withPHIDs(array($ref_phid))
|
|
->executeOne();
|
|
if (!$ref) {
|
|
$e_ref = pht('Invalid');
|
|
$errors[] = pht(
|
|
'You must select a branch from this repository to land this '.
|
|
'revision onto.');
|
|
}
|
|
}
|
|
|
|
if (!$errors) {
|
|
// NOTE: The operation is locked to the current active diff, so if the
|
|
// revision is updated before the operation applies nothing sneaky
|
|
// occurs.
|
|
|
|
$target = 'branch:'.$ref->getRefName();
|
|
|
|
$operation = DrydockRepositoryOperation::initializeNewOperation($op)
|
|
->setAuthorPHID($viewer->getPHID())
|
|
->setObjectPHID($revision->getPHID())
|
|
->setRepositoryPHID($repository->getPHID())
|
|
->setRepositoryTarget($target)
|
|
->setProperty('differential.diffPHID', $diff->getPHID());
|
|
|
|
$operation->save();
|
|
$operation->scheduleUpdate();
|
|
|
|
return id(new AphrontRedirectResponse())
|
|
->setURI($detail_uri);
|
|
}
|
|
}
|
|
|
|
$ref_datasource = id(new DiffusionRefDatasource())
|
|
->setParameters(
|
|
array(
|
|
'repositoryPHIDs' => array($repository->getPHID()),
|
|
'refTypes' => $this->getTargetableRefTypes(),
|
|
));
|
|
|
|
$form = id(new AphrontFormView())
|
|
->setUser($viewer)
|
|
->appendRemarkupInstructions(
|
|
pht(
|
|
'(NOTE) This feature is new and experimental.'))
|
|
->appendControl(
|
|
id(new AphrontFormTokenizerControl())
|
|
->setLabel(pht('Onto Branch'))
|
|
->setName('refPHIDs')
|
|
->setLimit(1)
|
|
->setError($e_ref)
|
|
->setValue($v_ref)
|
|
->setDatasource($ref_datasource));
|
|
|
|
return $this->newDialog()
|
|
->setWidth(AphrontDialogView::WIDTH_FORM)
|
|
->setTitle(pht('Land Revision'))
|
|
->setErrors($errors)
|
|
->appendForm($form)
|
|
->addCancelButton($detail_uri)
|
|
->addSubmitButton(pht('Land Revision'));
|
|
}
|
|
|
|
private function newRefQuery(PhabricatorRepository $repository) {
|
|
$viewer = $this->getViewer();
|
|
|
|
return id(new PhabricatorRepositoryRefCursorQuery())
|
|
->setViewer($viewer)
|
|
->withRepositoryPHIDs(array($repository->getPHID()))
|
|
->withRefTypes($this->getTargetableRefTypes());
|
|
}
|
|
|
|
private function getTargetableRefTypes() {
|
|
return array(
|
|
PhabricatorRepositoryRefCursor::TYPE_BRANCH,
|
|
);
|
|
}
|
|
|
|
private function loadDefaultRef(
|
|
PhabricatorRepository $repository,
|
|
DifferentialDiff $diff) {
|
|
$default_name = $this->getDefaultRefName($repository, $diff);
|
|
|
|
if (!strlen($default_name)) {
|
|
return null;
|
|
}
|
|
|
|
return $this->newRefQuery($repository)
|
|
->withRefNames(array($default_name))
|
|
->executeOne();
|
|
}
|
|
|
|
private function getDefaultRefName(
|
|
PhabricatorRepository $repository,
|
|
DifferentialDiff $diff) {
|
|
|
|
$onto = $diff->loadTargetBranch();
|
|
if ($onto !== null) {
|
|
return $onto;
|
|
}
|
|
|
|
return $repository->getDefaultBranch();
|
|
}
|
|
|
|
}
|