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:
parent
709c9cb6fb
commit
a30378a34a
2 changed files with 154 additions and 77 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue