Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lands a branch by rebasing, merging and amending it.
|
|
|
|
*
|
|
|
|
* @group workflow
|
|
|
|
*/
|
2012-01-31 21:07:05 +01:00
|
|
|
final class ArcanistLandWorkflow extends ArcanistBaseWorkflow {
|
2012-12-03 22:03:13 +01:00
|
|
|
private $isGit;
|
|
|
|
|
|
|
|
private $oldBranch;
|
|
|
|
private $branch;
|
|
|
|
private $onto;
|
|
|
|
private $ontoRemoteBranch;
|
|
|
|
private $remote;
|
|
|
|
private $useSquash;
|
|
|
|
private $keepBranch;
|
|
|
|
|
|
|
|
private $revision;
|
|
|
|
private $message;
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
Make Arcanist workflow names explicit
Summary:
Currently, adding a new workflow requires you to override ArcanistConfiguration, which is messy. Instead, just load everything that extends ArcanistBaseWorkflow.
Remove all the rules tying workflow names to class names through arcane incantations.
This has a very small performance cost in that we need to load every Workflow class every time now, but we don't hit __init__ and such anymore and it was pretty negligible on my machine (98ms vs 104ms or something).
Test Plan: Ran "arc help", "arc which", "arc diff", etc.
Reviewers: edward, vrana, btrahan
Reviewed By: edward
CC: aran, zeeg
Differential Revision: https://secure.phabricator.com/D3691
2012-10-17 17:35:03 +02:00
|
|
|
public function getWorkflowName() {
|
|
|
|
return 'land';
|
|
|
|
}
|
|
|
|
|
2012-03-05 19:02:37 +01:00
|
|
|
public function getCommandSynopses() {
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
return phutil_console_format(<<<EOTEXT
|
2012-04-23 23:09:29 +02:00
|
|
|
**land** [__options__] [__branch__] [--onto __master__]
|
2012-03-05 19:02:37 +01:00
|
|
|
EOTEXT
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getCommandHelp() {
|
|
|
|
return phutil_console_format(<<<EOTEXT
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
Supports: git
|
|
|
|
|
|
|
|
Land an accepted change (currently sitting in local feature branch
|
|
|
|
__branch__) onto __master__ and push it to the remote. Then, delete
|
2012-04-23 23:09:29 +02:00
|
|
|
the feature branch. If you omit __branch__, the current branch will
|
|
|
|
be used.
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
|
|
|
In mutable repositories, this will perform a --squash merge (the
|
|
|
|
entire branch will be represented by one commit on __master__). In
|
2012-02-20 21:51:14 +01:00
|
|
|
immutable repositories (or when --merge is provided), it will perform
|
|
|
|
a --no-ff merge (the branch will always be merged into __master__ with
|
|
|
|
a merge commit).
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
EOTEXT
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function requiresWorkingCopy() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function requiresConduit() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function requiresAuthentication() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function requiresRepositoryAPI() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getArguments() {
|
|
|
|
return array(
|
|
|
|
'onto' => array(
|
|
|
|
'param' => 'master',
|
|
|
|
'help' => "Land feature branch onto a branch other than ".
|
2012-03-23 02:20:22 +01:00
|
|
|
"'master' (default). You can change the default by setting ".
|
2012-06-20 21:29:07 +02:00
|
|
|
"'arc.land.onto.default' with `arc set-config` or for the ".
|
|
|
|
"entire project in .arcconfig.",
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
),
|
|
|
|
'hold' => array(
|
|
|
|
'help' => "Prepare the change to be pushed, but do not actually ".
|
|
|
|
"push it.",
|
|
|
|
),
|
|
|
|
'keep-branch' => array(
|
|
|
|
'help' => "Keep the feature branch after pushing changes to the ".
|
|
|
|
"remote (by default, it is deleted).",
|
|
|
|
),
|
|
|
|
'remote' => array(
|
|
|
|
'param' => 'origin',
|
|
|
|
'help' => "Push to a remote other than 'origin' (default).",
|
|
|
|
),
|
2012-02-20 21:51:14 +01:00
|
|
|
'merge' => array(
|
|
|
|
'help' => 'Perform a --no-ff merge, not a --squash merge. If the '.
|
|
|
|
'project is marked as having an immutable history, this is '.
|
|
|
|
'the default behavior.',
|
|
|
|
),
|
2012-03-23 02:20:22 +01:00
|
|
|
'squash' => array(
|
|
|
|
'help' => 'Perform a --squash merge, not a --no-ff merge. If the '.
|
|
|
|
'project is marked as having a mutable history, this is '.
|
|
|
|
'the default behavior.',
|
|
|
|
'conflicts' => array(
|
|
|
|
'merge' => '--merge and --squash are conflicting merge strategies.',
|
|
|
|
),
|
|
|
|
),
|
2012-05-10 21:14:53 +02:00
|
|
|
'delete-remote' => array(
|
|
|
|
'help' => 'Delete the feature branch in the remote after '.
|
|
|
|
'landing it.',
|
|
|
|
'conflicts' => array(
|
|
|
|
'keep-branch' => true,
|
|
|
|
),
|
|
|
|
),
|
2012-03-03 01:47:05 +01:00
|
|
|
'revision' => array(
|
|
|
|
'param' => 'id',
|
|
|
|
'help' => 'Use the message from a specific revision, rather than '.
|
|
|
|
'inferring the revision based on branch content.',
|
|
|
|
),
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
'*' => 'branch',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function run() {
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->readArguments();
|
|
|
|
$this->validate();
|
|
|
|
$this->findRevision();
|
|
|
|
$this->pullFromRemote();
|
|
|
|
|
|
|
|
if ($this->useSquash) {
|
|
|
|
$this->rebase();
|
|
|
|
$this->squash();
|
|
|
|
} else {
|
|
|
|
$this->merge();
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->push();
|
|
|
|
if (!$this->keepBranch) {
|
|
|
|
$this->cleanupBranch();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we were on some branch A and the user ran "arc land B",
|
|
|
|
// switch back to A.
|
|
|
|
if ($this->oldBranch != $this->branch && $this->oldBranch != $this->onto) {
|
|
|
|
$repository_api = $this->getRepositoryAPI();
|
|
|
|
$repository_api->execxLocal(
|
|
|
|
'checkout %s',
|
|
|
|
$this->oldBranch);
|
|
|
|
echo phutil_console_format(
|
|
|
|
"Switched back to branch **%s**.\n",
|
|
|
|
$this->oldBranch);
|
|
|
|
}
|
|
|
|
|
|
|
|
echo "Done.\n";
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function readArguments() {
|
2012-04-23 23:09:29 +02:00
|
|
|
$repository_api = $this->getRepositoryAPI();
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->isGit = $repository_api instanceof ArcanistGitAPI;
|
|
|
|
|
|
|
|
if (!$this->isGit) {
|
2012-04-23 23:09:29 +02:00
|
|
|
throw new ArcanistUsageException("'arc land' only supports git.");
|
|
|
|
}
|
|
|
|
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
$branch = $this->getArgument('branch');
|
2012-04-23 23:09:29 +02:00
|
|
|
if (empty($branch)) {
|
|
|
|
$branch = $repository_api->getBranchName();
|
2012-12-03 22:03:13 +01:00
|
|
|
|
2012-04-23 23:09:29 +02:00
|
|
|
if ($branch) {
|
|
|
|
echo "Landing current branch '{$branch}'.\n";
|
|
|
|
$branch = array($branch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
if (count($branch) !== 1) {
|
|
|
|
throw new ArcanistUsageException(
|
|
|
|
"Specify exactly one branch to land changes from.");
|
|
|
|
}
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->branch = head($branch);
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-03-23 02:20:22 +01:00
|
|
|
$onto_default = nonempty(
|
2012-06-20 21:29:07 +02:00
|
|
|
$this->getWorkingCopy()->getConfigFromAnySource('arc.land.onto.default'),
|
2012-03-23 02:20:22 +01:00
|
|
|
'master');
|
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->remote = $this->getArgument('remote', 'origin');
|
|
|
|
$this->onto = $this->getArgument('onto', $onto_default);
|
|
|
|
$this->keepBranch = $this->getArgument('keep-branch');
|
|
|
|
|
|
|
|
if ($this->getArgument('merge')) {
|
|
|
|
$this->useSquash = false;
|
|
|
|
} else if ($this->getArgument('squash')) {
|
|
|
|
$this->useSquash = true;
|
|
|
|
} else {
|
|
|
|
$this->useSquash = !$this->isHistoryImmutable();
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->ontoRemoteBranch = $this->remote.'/'.$this->onto;
|
|
|
|
|
|
|
|
$this->oldBranch = $repository_api->getBranchName();
|
|
|
|
}
|
2012-03-23 02:20:22 +01:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
private function validate() {
|
|
|
|
$repository_api = $this->getRepositoryAPI();
|
2012-05-23 20:40:20 +02:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
if ($this->onto == $this->branch) {
|
2012-05-23 20:40:20 +02:00
|
|
|
$message =
|
2012-05-10 21:14:53 +02:00
|
|
|
"You can not land a branch onto itself -- you are trying to land ".
|
2012-12-03 22:03:13 +01:00
|
|
|
"'{$this->branch}' onto '{$this->onto}'. For more information on ".
|
|
|
|
"how to push changes, see 'Pushing and Closing Revisions' in ".
|
2012-05-23 20:40:20 +02:00
|
|
|
"'Arcanist User Guide: arc diff' in the documentation.";
|
2012-12-03 22:03:13 +01:00
|
|
|
if (!$this->isHistoryImmutable()) {
|
2012-05-23 20:40:20 +02:00
|
|
|
$message .= " You may be able to 'arc amend' instead.";
|
|
|
|
}
|
|
|
|
throw new ArcanistUsageException($message);
|
2012-05-10 21:14:53 +02:00
|
|
|
}
|
|
|
|
|
2012-03-23 02:20:22 +01:00
|
|
|
list($err) = $repository_api->execManualLocal(
|
|
|
|
'rev-parse --verify %s',
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->branch);
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
|
|
|
if ($err) {
|
|
|
|
throw new ArcanistUsageException(
|
2012-12-03 22:03:13 +01:00
|
|
|
"Branch '{$this->branch}' does not exist.");
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
}
|
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->requireCleanWorkingCopy();
|
|
|
|
}
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
private function findRevision() {
|
|
|
|
$repository_api = $this->getRepositoryAPI();
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
$repository_api->parseRelativeLocalCommit(array($this->ontoRemoteBranch));
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-03-03 01:47:05 +01:00
|
|
|
$revision_id = $this->getArgument('revision');
|
|
|
|
if ($revision_id) {
|
|
|
|
$revision_id = $this->normalizeRevisionID($revision_id);
|
|
|
|
$revisions = $this->getConduit()->callMethodSynchronous(
|
|
|
|
'differential.query',
|
|
|
|
array(
|
|
|
|
'ids' => array($revision_id),
|
|
|
|
));
|
|
|
|
if (!$revisions) {
|
|
|
|
throw new ArcanistUsageException("No such revision 'D{$revision_id}'!");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$revisions = $repository_api->loadWorkingCopyDifferentialRevisions(
|
|
|
|
$this->getConduit(),
|
|
|
|
array(
|
|
|
|
'authors' => array($this->getUserPHID()),
|
|
|
|
));
|
|
|
|
}
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
|
|
|
if (!count($revisions)) {
|
|
|
|
throw new ArcanistUsageException(
|
2012-12-03 22:03:13 +01:00
|
|
|
"arc can not identify which revision exists on branch ".
|
|
|
|
"'{$this->branch}'. Update the revision with recent changes ".
|
|
|
|
"to synchronize the branch name and hashes, or use 'arc amend' ".
|
|
|
|
"to amend the commit message at HEAD, or use '--revision <id>' ".
|
|
|
|
"to select a revision explicitly.");
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
} else if (count($revisions) > 1) {
|
|
|
|
$message =
|
2012-12-03 22:03:13 +01:00
|
|
|
"There are multiple revisions on feature branch '{$this->branch}' ".
|
|
|
|
"which are not present on '{$onto}':\n\n".
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
$this->renderRevisionList($revisions)."\n".
|
2012-03-03 01:47:05 +01:00
|
|
|
"Separate these revisions onto different branches, or use ".
|
|
|
|
"'--revision <id>' to select one.";
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
throw new ArcanistUsageException($message);
|
|
|
|
}
|
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->revision = head($revisions);
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
$rev_status = $this->revision['status'];
|
|
|
|
$rev_id = $this->revision['id'];
|
|
|
|
$rev_title = $this->revision['title'];
|
|
|
|
|
|
|
|
if ($rev_status != ArcanistDifferentialRevisionStatus::ACCEPTED) {
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
$ok = phutil_console_confirm(
|
2012-12-03 22:03:13 +01:00
|
|
|
"Revision 'D{$rev_id}: {$rev_title}' has not been ".
|
|
|
|
"accepted. Continue anyway?");
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
if (!$ok) {
|
|
|
|
throw new ArcanistUserAbortException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->message = $this->getConduit()->callMethodSynchronous(
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
'differential.getcommitmessage',
|
|
|
|
array(
|
2012-12-03 22:03:13 +01:00
|
|
|
'revision_id' => $rev_id,
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
));
|
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
echo "Landing revision 'D{$rev_id}: ".
|
|
|
|
"{$rev_title}'...\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
private function pullFromRemote() {
|
|
|
|
$repository_api = $this->getRepositoryAPI();
|
|
|
|
$repository_api->execxLocal('checkout %s', $this->onto);
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
echo phutil_console_format(
|
|
|
|
"Switched to branch **%s**. Updating branch...\n",
|
|
|
|
$this->onto);
|
|
|
|
|
|
|
|
$repository_api->execxLocal('pull --ff-only');
|
|
|
|
|
|
|
|
list($out) = $repository_api->execxLocal(
|
|
|
|
'log %s/%s..%s',
|
|
|
|
$this->remote,
|
|
|
|
$this->onto,
|
|
|
|
$this->onto);
|
|
|
|
if (strlen(trim($out))) {
|
|
|
|
throw new ArcanistUsageException(
|
|
|
|
"Local branch '{$this->onto}' is ahead of remote branch ".
|
|
|
|
"'{$this->ontoRemoteBranch}', so landing a feature branch ".
|
|
|
|
"would push additional changes. Push or reset the changes ".
|
|
|
|
"in '{$this->onto}' before running 'arc land'.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function rebase() {
|
|
|
|
$repository_api = $this->getRepositoryAPI();
|
|
|
|
$repository_api->execxLocal(
|
|
|
|
'checkout %s',
|
|
|
|
$this->branch);
|
|
|
|
|
|
|
|
echo phutil_console_format(
|
|
|
|
"Switched to branch **%s**. Identifying and merging...\n",
|
|
|
|
$this->branch);
|
|
|
|
|
|
|
|
if ($this->useSquash) {
|
2012-03-23 02:20:22 +01:00
|
|
|
chdir($repository_api->getPath());
|
2012-12-03 22:03:13 +01:00
|
|
|
$err = phutil_passthru('git rebase %s', $this->onto);
|
|
|
|
|
2012-01-27 02:41:11 +01:00
|
|
|
if ($err) {
|
|
|
|
throw new ArcanistUsageException(
|
2012-12-03 22:03:13 +01:00
|
|
|
"'git rebase {$this->onto}' failed. ".
|
|
|
|
"You can abort with 'git rebase --abort', ".
|
|
|
|
"or resolve conflicts and use 'git rebase ".
|
|
|
|
"--continue' to continue forward. After resolving the rebase, ".
|
|
|
|
"run 'arc land' again.");
|
2012-01-27 02:41:11 +01:00
|
|
|
}
|
2012-12-03 22:03:13 +01:00
|
|
|
|
|
|
|
// Now that we've rebased, the merge-base of origin/master and HEAD may
|
|
|
|
// be different. Reparse the relative commit.
|
|
|
|
$repository_api->parseRelativeLocalCommit(array($this->ontoRemoteBranch));
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
}
|
2012-12-03 22:03:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private function squash() {
|
|
|
|
$repository_api = $this->getRepositoryAPI();
|
|
|
|
$repository_api->execxLocal('checkout %s', $this->onto);
|
|
|
|
|
|
|
|
$repository_api->execxLocal(
|
|
|
|
'merge --squash --ff-only %s',
|
|
|
|
$this->branch);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function merge() {
|
|
|
|
$repository_api = $this->getRepositoryAPI();
|
|
|
|
|
|
|
|
// In immutable histories, do a --no-ff merge to force a merge commit with
|
|
|
|
// the right message.
|
|
|
|
$repository_api->execxLocal('checkout %s', $this->onto);
|
|
|
|
|
|
|
|
chdir($repository_api->getPath());
|
|
|
|
$err = phutil_passthru(
|
|
|
|
'git merge --no-ff --no-commit %s',
|
|
|
|
$this->branch);
|
|
|
|
|
|
|
|
if ($err) {
|
|
|
|
throw new ArcanistUsageException(
|
|
|
|
"'git merge' failed. Your working copy has been left in a partially ".
|
|
|
|
"merged state. You can: abort with 'git merge --abort'; or follow ".
|
|
|
|
"the instructions to complete the merge.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function push() {
|
|
|
|
$repository_api = $this->getRepositoryAPI();
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-05-03 01:48:44 +02:00
|
|
|
$tmp_file = new TempFile();
|
2012-12-03 22:03:13 +01:00
|
|
|
Filesystem::writeFile($tmp_file, $this->message);
|
|
|
|
|
2012-05-03 01:48:44 +02:00
|
|
|
$repository_api->execxLocal(
|
|
|
|
'commit -F %s',
|
|
|
|
$tmp_file);
|
|
|
|
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
if ($this->getArgument('hold')) {
|
|
|
|
echo phutil_console_format(
|
|
|
|
"Holding change in **%s**: it has NOT been pushed yet.\n",
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->onto);
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
} else {
|
|
|
|
echo "Pushing change...\n\n";
|
|
|
|
|
2012-03-23 02:20:22 +01:00
|
|
|
chdir($repository_api->getPath());
|
2012-12-03 22:03:13 +01:00
|
|
|
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
$err = phutil_passthru(
|
2012-03-23 02:20:22 +01:00
|
|
|
'git push %s %s',
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->remote,
|
|
|
|
$this->onto);
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
|
|
|
if ($err) {
|
2012-12-03 22:03:13 +01:00
|
|
|
$repo_command = $repository_api->getSourceControlSystemName();
|
|
|
|
throw new ArcanistUsageException("'{$repo_command} push' failed.");
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
}
|
|
|
|
|
2012-02-01 23:32:43 +01:00
|
|
|
$mark_workflow = $this->buildChildWorkflow(
|
2012-04-17 22:51:10 +02:00
|
|
|
'close-revision',
|
2012-02-01 23:32:43 +01:00
|
|
|
array(
|
|
|
|
'--finalize',
|
|
|
|
'--quiet',
|
2012-12-03 22:03:13 +01:00
|
|
|
$this->revision['id'],
|
2012-02-01 23:32:43 +01:00
|
|
|
));
|
|
|
|
$mark_workflow->run();
|
|
|
|
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
echo "\n";
|
|
|
|
}
|
2012-12-03 22:03:13 +01:00
|
|
|
}
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
private function cleanupBranch() {
|
|
|
|
$repository_api = $this->getRepositoryAPI();
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
echo "Cleaning up feature branch...\n";
|
|
|
|
list($ref) = $repository_api->execxLocal(
|
|
|
|
'rev-parse --verify %s',
|
|
|
|
$this->branch);
|
|
|
|
$ref = trim($ref);
|
|
|
|
$recovery_command = csprintf(
|
|
|
|
'git checkout -b %s %s',
|
|
|
|
$this->branch,
|
|
|
|
$ref);
|
|
|
|
echo "(Use `{$recovery_command}` if you want it back.)\n";
|
|
|
|
$repository_api->execxLocal(
|
|
|
|
'branch -D %s',
|
|
|
|
$this->branch);
|
2012-02-04 00:44:59 +01:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
if ($this->getArgument('delete-remote')) {
|
|
|
|
list($err, $ref) = $repository_api->execManualLocal(
|
|
|
|
'rev-parse --verify %s/%s',
|
|
|
|
$this->remote,
|
|
|
|
$this->branch);
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
|
2012-12-03 22:03:13 +01:00
|
|
|
if ($err) {
|
|
|
|
echo "No remote feature branch to clean up.\n";
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// NOTE: In Git, you delete a remote branch by pushing it with a
|
|
|
|
// colon in front of its name:
|
|
|
|
//
|
|
|
|
// git push <remote> :<branch>
|
|
|
|
|
|
|
|
echo "Cleaning up remote feature branch...\n";
|
|
|
|
$repository_api->execxLocal(
|
|
|
|
'push %s :%s',
|
|
|
|
$this->remote,
|
|
|
|
$this->branch);
|
|
|
|
}
|
|
|
|
}
|
Add "arc land" as a first-class workflow
Summary:
This is a fancy version of "land.sh" that uses "git merge --squash" and
"arc which" to cover more cases.
Test Plan:
Ran "arc land" against various repository states (no such branch, not
accepted, valid, etc). Things seemed OK. There are basically an infinite number
of states here so it's hard to test exhaustively.
Reviewers: cpiro, btrahan, jungejason, davidreuss
Reviewed By: davidreuss
CC: zeeg, aran, epriestley, davidreuss
Maniphest Tasks: T787, T723
Differential Revision: https://secure.phabricator.com/D1488
2012-01-26 00:10:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function getSupportedRevisionControlSystems() {
|
|
|
|
return array('git');
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|