1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-22 06:42:41 +01:00

Update "arc help land"

Summary: Ref T13546. Provide more up-to-date help about the "land" workflow, including modern flags and behavior.

Test Plan: Read "arc help land".

Maniphest Tasks: T13546

Differential Revision: https://secure.phabricator.com/D21326
This commit is contained in:
epriestley 2020-06-07 09:09:45 -07:00
parent 709c9cb6fb
commit a30378a34a
2 changed files with 154 additions and 77 deletions

View file

@ -10,6 +10,7 @@ final class ArcanistWorkflowArgument
private $isPathArgument; private $isPathArgument;
private $shortFlag; private $shortFlag;
private $repeatable; private $repeatable;
private $relatedConfig = array();
public function setKey($key) { public function setKey($key) {
$this->key = $key; $this->key = $key;
@ -47,6 +48,15 @@ final class ArcanistWorkflowArgument
return $this->repeatable; return $this->repeatable;
} }
public function addRelatedConfig($related_config) {
$this->relatedConfig[] = $related_config;
return $this;
}
public function getRelatedConfig() {
return $this->relatedConfig;
}
public function getPhutilSpecification() { public function getPhutilSpecification() {
$spec = array( $spec = array(
'name' => $this->getKey(), 'name' => $this->getKey(),
@ -63,6 +73,20 @@ final class ArcanistWorkflowArgument
$help = $this->getHelp(); $help = $this->getHelp();
if ($help !== null) { if ($help !== null) {
$config = $this->getRelatedConfig();
if ($config) {
$more = array();
foreach ($this->getRelatedConfig() as $config) {
$more[] = tsprintf(
'%s **%s**',
pht('Related configuration:'),
$config);
}
$more = phutil_glue($more, "\n");
$help = tsprintf("%B\n\n%B", $help, $more);
}
$spec['help'] = $help; $spec['help'] = $help;
} }
@ -80,6 +104,10 @@ final class ArcanistWorkflowArgument
} }
public function setHelp($help) { public function setHelp($help) {
if (is_array($help)) {
$help = implode("\n\n", $help);
}
$this->help = $help; $this->help = $help;
return $this; return $this;
} }

View file

@ -12,82 +12,111 @@ final class ArcanistLandWorkflow
public function getWorkflowInformation() { public function getWorkflowInformation() {
$help = pht(<<<EOTEXT $help = pht(<<<EOTEXT
Supports: git, git/p4, hg Supports: git, git/p4, git/svn, hg
Publish an accepted revision after review. This command is the last Publish accepted revisions after review. This command is the last step in the
step in the standard Differential code review workflow. standard Differential code review workflow.
This command merges and pushes changes associated with an accepted To publish changes in local branch or bookmark "feature1", you will usually
revision that are currently sitting in __ref__, which is usually the run this command:
name of a local branch. Without __ref__, the current working copy
state will be used.
Under Git: branches, tags, and arbitrary commits (detached HEADs) **$ arc land feature1**
may be landed.
Under Git/Perforce: branches, tags, and arbitrary commits may This workflow merges and pushes changes associated with revisions that are
be submitted. ancestors of __ref__. Without __ref__, the current working copy state will be
used. You can specify multiple __ref__ arguments to publish multiple changes at
once.
Under Mercurial: branches and bookmarks may be landed, but only A __ref__ can be any symbol which identifies a commit: a branch name, a tag
onto a target of the same type. See T3855. name, a bookmark name, a topic name, a raw commit hash, a symbolic reference,
etc.
The workflow selects a target branch to land onto and a remote where When you provide a __ref__, all unpublished changes which are present in
the change will be pushed to. ancestors of that __ref__ will be selected for publishing.
A target branch is selected by examining these sources in order: For example, if you provide local branch "feature3" as a __ref__ argument, that
may also select the changes in "feature1" and "feature2" (if they are ancestors
of "feature3"). If you stack changes in a single local branch, all commits in
the stack may be selected.
- the **--onto** flag; The workflow merges unpublished changes reachable from __ref__ "into" some
- the upstream of the branch targeted by the land operation, intermediate branch, then pushes the combined state "onto" some destination
recursively (Git only); branch (or list of branches).
- the __arc.land.onto.default__ configuration setting;
(In Mercurial, the "into" and "onto" branches may be bookmarks instead.)
In the most common case, there is only one "onto" branch (often "master" or
"default" or some similar branch) and the "into" branch is the same branch. For
example, it is common to merge local feature branch "feature1" into
"origin/master", then push it onto "origin/master".
The list of "onto" branches is selected by examining these sources in order:
- the **--onto** flags;
- the __arc.land.onto__ configuration setting;
- (in Git) the upstream of the branch targeted by the land operation,
recursively;
- or by falling back to a standard default: - or by falling back to a standard default:
- "master" in Git; - (in Git) "master";
- "default" in Mercurial. - (in Mercurial) "default".
A remote is selected by examining these sources in order: The remote to push "onto" is selected by examining these sources in order:
- the **--remote** flag; - the **--onto-remote** flag;
- the upstream of the current branch, recursively (Git only); - the __arc.land.onto-remote__ configuration setting;
- the special "p4" remote which indicates a repository has - (in Git) the upstream of the current branch, recursively;
been synchronized with Perforce (Git only); - (in Git) the special "p4" remote which indicates a repository has
been synchronized with Perforce;
- or by falling back to a standard default: - or by falling back to a standard default:
- "origin" in Git; - (in Git) "origin";
- the default remote in Mercurial. - (in Mercurial) "default".
After selecting a target branch and a remote, the commits which will The branch to merge "into" is selected by examining these sources in order:
be landed are printed.
With **--preview**, execution stops here, before the change is - the **--into** flag;
merged. - the **--into-empty** flag;
- or by falling back to the first "onto" branch.
The change is merged with the changes in the target branch, The remote to merge "into" is selected by examining these sources in order:
following these rules:
In repositories with mutable history or with **--squash**, this will - the **--into-remote** flag;
perform a squash merge (the entire branch will be represented as one - the **--into-local** flag (which disables fetching before merging);
commit after the merge). - or by falling back to the "onto" remote.
In repositories with immutable history or with **--merge**, this will After selecting remotes and branches, the commits which will land are printed.
perform a strict merge (a merge commit will always be created, and
local commits will be preserved).
The resulting commit will be given an up-to-date commit message With **--preview**, execution stops here, before the change is merged.
The "into" branch is fetched from the "into" remote (unless **--into-local** or
**--into-empty** are specified) and the changes are merged into the state in
the "into" branch according to the selected merge strategy.
The default merge strategy is "squash", which produces a single commit from
all local commits for each change. A different strategy can be selected with
the **--strategy** flag.
The resulting merged change will be given an up-to-date commit message
describing the final state of the revision in Differential. describing the final state of the revision in Differential.
In Git, the merge occurs in a detached HEAD. The local branch
reference (if one exists) is not updated yet.
With **--hold**, execution stops here, before the change is pushed. With **--hold**, execution stops here, before the change is pushed.
The change is pushed into the remote. The change is pushed onto all of the "onto" branches in the "onto" remote.
Consulting mystical sources of power, the workflow makes a guess If you are landing multiple changes, they are normally all merged locally and
about what state you wanted to end up in after the process finishes then all pushed in a single operation. Instead, you can merge and push them one
and the working copy is put into that state. at a time with **--incremental**.
The branch which was landed is deleted, unless the **--keep-branch** Under merge strategies which mutate history (including the default "squash"
flag was passed or the landing branch is the same as the target strategy), local refs which descend from commits that were published are
branch. now updated. For example, if you land "feature4", local branches "feature5" and
"feature6" may now be rebased on the published version of the change.
Once everything has been pushed, cleanup occurs. Consulting mystical sources of
power, the workflow makes a guess about what state you wanted to end up in
after the process finishes. The working copy is put into that state.
Any obsolete refs that point at commits which were published are deleted,
unless the **--keep-branch** flag is passed.
EOTEXT EOTEXT
); );
@ -102,49 +131,65 @@ EOTEXT
$this->newWorkflowArgument('hold') $this->newWorkflowArgument('hold')
->setHelp( ->setHelp(
pht( pht(
'Prepare the change to be pushed, but do not actually push it.')), 'Prepare the changes to be pushed, but do not actually push '.
'them.')),
$this->newWorkflowArgument('keep-branches') $this->newWorkflowArgument('keep-branches')
->setHelp( ->setHelp(
pht( pht(
'Keep local branches around after changes are pushed. By '. 'Keep local branches around after changes are pushed. By '.
'default, local branches are deleted after they land.')), 'default, local branches are deleted after the changes they '.
'contain are published.')),
$this->newWorkflowArgument('onto-remote') $this->newWorkflowArgument('onto-remote')
->setParameter('remote-name') ->setParameter('remote-name')
->setHelp(pht('Push to a remote other than the default.')), ->setHelp(pht('Push to a remote other than the default.'))
->addRelatedConfig('arc.land.onto-remote'),
// TODO: Formally allow flags to be bound to related configuration
// for documentation, e.g. "setRelatedConfiguration('arc.land.onto')".
$this->newWorkflowArgument('onto') $this->newWorkflowArgument('onto')
->setParameter('branch-name') ->setParameter('branch-name')
->setRepeatable(true) ->setRepeatable(true)
->addRelatedConfig('arc.land.onto')
->setHelp( ->setHelp(
array(
pht( pht(
'After merging, push changes onto a specified branch. '. 'After merging, push changes onto a specified branch.'),
'Specifying this flag multiple times will push multiple '. pht(
'branches.')), 'Specifying this flag multiple times will push to multiple '.
'branches.'),
)),
$this->newWorkflowArgument('strategy') $this->newWorkflowArgument('strategy')
->setParameter('strategy-name') ->setParameter('strategy-name')
->addRelatedConfig('arc.land.strategy')
->setHelp( ->setHelp(
array(
pht( pht(
// TODO: Improve this. 'Merge using a particular strategy. Supported strategies are '.
'Merge using a particular strategy.')), '"squash" and "merge".'),
pht(
'The "squash" strategy collapses multiple local commits into '.
'a single commit when publishing. It produces a linear '.
'published history (but discards local checkpoint commits). '.
'This is the default strategy.'),
pht(
'The "merge" strategy generates a merge commit when publishing '.
'that retains local checkpoint commits (but produces a '.
'nonlinear published history). Select this strategy if you do '.
'not want "arc land" to discard checkpoint commits.'),
)),
$this->newWorkflowArgument('revision') $this->newWorkflowArgument('revision')
->setParameter('revision-identifier') ->setParameter('revision-identifier')
->setHelp( ->setHelp(
pht( pht(
'Land a specific revision, rather than determining the revisions '. 'Land a specific revision, rather than determining revisions '.
'from the commits that are landing.')), 'automatically from the commits that are landing.')),
$this->newWorkflowArgument('preview') $this->newWorkflowArgument('preview')
->setHelp( ->setHelp(
pht( pht(
'Shows the changes that will land. Does not modify the working '. 'Show the changes that will land. Does not modify the working '.
'copy or the remote.')), 'copy or the remote.')),
$this->newWorkflowArgument('into') $this->newWorkflowArgument('into')
->setParameter('commit-ref') ->setParameter('commit-ref')
->setHelp( ->setHelp(
pht( pht(
'Specifies the state to merge into. By default, this is the same '. 'Specify the state to merge into. By default, this is the same '.
'as the "onto" ref.')), 'as the "onto" ref.')),
$this->newWorkflowArgument('into-remote') $this->newWorkflowArgument('into-remote')
->setParameter('remote-name') ->setParameter('remote-name')
@ -166,13 +211,17 @@ EOTEXT
'"into" state is not specified.')), '"into" state is not specified.')),
$this->newWorkflowArgument('incremental') $this->newWorkflowArgument('incremental')
->setHelp( ->setHelp(
array(
pht( pht(
'When landing multiple revisions at once, push and rebase '. 'When landing multiple revisions at once, push and rebase '.
'after each operation instead of waiting until all merges '. 'after each merge completes instead of waiting until all '.
'are completed. This is slower than the default behavior and '. 'merges are completed to push.'),
'not atomic, but may make it easier to resolve conflicts and '. pht(
'land complicated changes by letting you make progress one '. 'This is slower than the default behavior and not atomic, '.
'step at a time.')), 'but may make it easier to resolve conflicts and land '.
'complicated changes by allowing you to make progress one '.
'step at a time.'),
)),
$this->newWorkflowArgument('ref') $this->newWorkflowArgument('ref')
->setWildcard(true), ->setWildcard(true),
); );