Land Revision button for hosted git repos
Summary:
ref T182.
Simple approach of clone, patch, push. While waiting for drydock, implement a hackish mutex
setup for the workspace, which should work ok as long as there's only one committer who is
carefull about theses things.
Less obvious note: This is taking the both author and commiter's 'primary email' for the commit -
which might rub some people wrong.
Test Plan:
With a hosted repo, created some diffs and landed them.
Also clicked button for some error cases, got the right error message.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley
CC: hach-que, Korvin, epriestley, aran
Maniphest Tasks: T182
Differential Revision: https://secure.phabricator.com/D7486
2013-11-05 22:00:12 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class DifferentialLandingToHostedGit
|
|
|
|
extends DifferentialLandingStrategy {
|
|
|
|
|
|
|
|
public function processLandRequest(
|
|
|
|
AphrontRequest $request,
|
|
|
|
DifferentialRevision $revision,
|
|
|
|
PhabricatorRepository $repository) {
|
|
|
|
|
|
|
|
$viewer = $request->getUser();
|
|
|
|
|
|
|
|
$workspace = $this->getGitWorkspace($repository);
|
|
|
|
|
|
|
|
try {
|
|
|
|
$this->commitRevisionToWorkspace(
|
|
|
|
$revision,
|
|
|
|
$workspace,
|
|
|
|
$viewer);
|
|
|
|
} catch (Exception $e) {
|
|
|
|
throw new PhutilProxyException(
|
|
|
|
'Failed to commit patch',
|
|
|
|
$e);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$this->pushWorkspaceRepository(
|
|
|
|
$repository,
|
|
|
|
$workspace,
|
|
|
|
$viewer);
|
|
|
|
} catch (Exception $e) {
|
|
|
|
throw new PhutilProxyException(
|
|
|
|
'Failed to push changes upstream',
|
|
|
|
$e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function commitRevisionToWorkspace(
|
|
|
|
DifferentialRevision $revision,
|
|
|
|
ArcanistRepositoryAPI $workspace,
|
|
|
|
PhabricatorUser $user) {
|
|
|
|
|
|
|
|
$diff_id = $revision->loadActiveDiff()->getID();
|
|
|
|
|
|
|
|
$call = new ConduitCall(
|
|
|
|
'differential.getrawdiff',
|
|
|
|
array(
|
|
|
|
'diffID' => $diff_id,
|
|
|
|
));
|
|
|
|
|
|
|
|
$call->setUser($user);
|
|
|
|
$raw_diff = $call->execute();
|
|
|
|
|
|
|
|
$missing_binary =
|
|
|
|
"\nindex "
|
|
|
|
. "0000000000000000000000000000000000000000.."
|
|
|
|
. "0000000000000000000000000000000000000000\n";
|
|
|
|
if (strpos($raw_diff, $missing_binary) !== false) {
|
|
|
|
throw new Exception("Patch is missing content for a binary file");
|
|
|
|
}
|
|
|
|
|
|
|
|
$future = $workspace->execFutureLocal('apply --index -');
|
|
|
|
$future->write($raw_diff);
|
|
|
|
$future->resolvex();
|
|
|
|
|
|
|
|
$workspace->reloadWorkingCopy();
|
|
|
|
|
|
|
|
$call = new ConduitCall(
|
|
|
|
'differential.getcommitmessage',
|
|
|
|
array(
|
|
|
|
'revision_id' => $revision->getID(),
|
|
|
|
));
|
|
|
|
|
|
|
|
$call->setUser($user);
|
|
|
|
$message = $call->execute();
|
|
|
|
|
|
|
|
$author = id(new PhabricatorUser())->loadOneWhere(
|
|
|
|
'phid = %s',
|
|
|
|
$revision->getAuthorPHID());
|
|
|
|
|
|
|
|
$author_string = sprintf(
|
|
|
|
'%s <%s>',
|
|
|
|
$author->getRealName(),
|
|
|
|
$author->loadPrimaryEmailAddress());
|
|
|
|
$author_date = $revision->getDateCreated();
|
|
|
|
|
|
|
|
$workspace->execxLocal(
|
|
|
|
'-c user.name=%s -c user.email=%s ' .
|
|
|
|
'commit --date=%s --author=%s '.
|
|
|
|
'--message=%s',
|
|
|
|
// -c will set the 'committer'
|
|
|
|
$user->getRealName(),
|
|
|
|
$user->loadPrimaryEmailAddress(),
|
|
|
|
$author_date,
|
|
|
|
$author_string,
|
|
|
|
$message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function pushWorkspaceRepository(
|
|
|
|
PhabricatorRepository $repository,
|
|
|
|
ArcanistRepositoryAPI $workspace,
|
|
|
|
PhabricatorUser $user) {
|
|
|
|
|
|
|
|
$workspace->execxLocal("push origin HEAD:master");
|
|
|
|
}
|
|
|
|
|
2014-01-30 18:07:50 +01:00
|
|
|
public function createMenuItem(
|
Land Revision button for hosted git repos
Summary:
ref T182.
Simple approach of clone, patch, push. While waiting for drydock, implement a hackish mutex
setup for the workspace, which should work ok as long as there's only one committer who is
carefull about theses things.
Less obvious note: This is taking the both author and commiter's 'primary email' for the commit -
which might rub some people wrong.
Test Plan:
With a hosted repo, created some diffs and landed them.
Also clicked button for some error cases, got the right error message.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley
CC: hach-que, Korvin, epriestley, aran
Maniphest Tasks: T182
Differential Revision: https://secure.phabricator.com/D7486
2013-11-05 22:00:12 +01:00
|
|
|
PhabricatorUser $viewer,
|
|
|
|
DifferentialRevision $revision,
|
|
|
|
PhabricatorRepository $repository) {
|
|
|
|
|
|
|
|
$vcs = $repository->getVersionControlSystem();
|
|
|
|
if ($vcs !== PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$repository->isHosted()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$repository->isWorkingCopyBare()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->createActionView(
|
|
|
|
$revision,
|
2014-01-30 18:07:50 +01:00
|
|
|
pht('Land to Hosted Repository'));
|
Land Revision button for hosted git repos
Summary:
ref T182.
Simple approach of clone, patch, push. While waiting for drydock, implement a hackish mutex
setup for the workspace, which should work ok as long as there's only one committer who is
carefull about theses things.
Less obvious note: This is taking the both author and commiter's 'primary email' for the commit -
which might rub some people wrong.
Test Plan:
With a hosted repo, created some diffs and landed them.
Also clicked button for some error cases, got the right error message.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley
CC: hach-que, Korvin, epriestley, aran
Maniphest Tasks: T182
Differential Revision: https://secure.phabricator.com/D7486
2013-11-05 22:00:12 +01:00
|
|
|
}
|
|
|
|
}
|