Page MenuHomePhabricator

D21340.diff
No OneTemporary

D21340.diff

diff --git a/src/land/ArcanistLandCommitSet.php b/src/land/ArcanistLandCommitSet.php
--- a/src/land/ArcanistLandCommitSet.php
+++ b/src/land/ArcanistLandCommitSet.php
@@ -5,6 +5,7 @@
private $revisionRef;
private $commits;
+ private $isPick;
public function setRevisionRef(ArcanistRevisionRef $revision_ref) {
$this->revisionRef = $revision_ref;
@@ -49,4 +50,23 @@
return false;
}
+ public function hasDirectSymbols() {
+ foreach ($this->commits as $commit) {
+ if ($commit->getDirectSymbols()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function setIsPick($is_pick) {
+ $this->isPick = $is_pick;
+ return $this;
+ }
+
+ public function getIsPick() {
+ return $this->isPick;
+ }
+
}
diff --git a/src/land/engine/ArcanistGitLandEngine.php b/src/land/engine/ArcanistGitLandEngine.php
--- a/src/land/engine/ArcanistGitLandEngine.php
+++ b/src/land/engine/ArcanistGitLandEngine.php
@@ -122,6 +122,7 @@
return;
}
+ $min_commit = head($set->getCommits())->getHash();
$old_commit = last($set->getCommits())->getHash();
$new_commit = $into_commit;
@@ -143,17 +144,38 @@
'Rebasing "%s" onto landed state...',
$branch_name));
+ // If we used "--pick" to select this commit, we want to rebase branches
+ // that descend from it onto its ancestor, not onto the landed change.
+
+ // For example, if the change sequence was "W", "X", "Y", "Z" and we
+ // landed "Y" onto "master" using "--pick", we want to rebase "Z" onto
+ // "X" (so "W" and "X", which it will often depend on, are still
+ // its ancestors), not onto the new "master".
+
+ if ($set->getIsPick()) {
+ $rebase_target = $min_commit.'^';
+ } else {
+ $rebase_target = $new_commit;
+ }
+
try {
$api->execxLocal(
'rebase --onto %s -- %s %s',
- $new_commit,
+ $rebase_target,
$old_commit,
$branch_name);
} catch (CommandException $ex) {
- // TODO: If we have a stashed state or are not running in incremental
- // mode: abort the rebase, restore the local state, and pop the stash.
- // Otherwise, drop the user out here.
- throw $ex;
+ $api->execManualLocal('rebase --abort');
+ $api->execManualLocal('reset --hard HEAD --');
+
+ $log->writeWarning(
+ pht('REBASE CONFLICT'),
+ pht(
+ 'Branch "%s" does not rebase cleanly from "%s" onto '.
+ '"%s", skipping.',
+ $branch_name,
+ $this->getDisplayHash($old_commit),
+ $this->getDisplayHash($rebase_target)));
}
}
}
diff --git a/src/land/engine/ArcanistLandEngine.php b/src/land/engine/ArcanistLandEngine.php
--- a/src/land/engine/ArcanistLandEngine.php
+++ b/src/land/engine/ArcanistLandEngine.php
@@ -29,6 +29,7 @@
private $localState;
private $hasUnpushedChanges;
+ private $pickArgument;
final public function setOntoRemote($onto_remote) {
$this->ontoRemote = $onto_remote;
@@ -75,6 +76,15 @@
return $this->intoEmpty;
}
+ final public function setPickArgument($pick_argument) {
+ $this->pickArgument = $pick_argument;
+ return $this;
+ }
+
+ final public function getPickArgument() {
+ return $this->pickArgument;
+ }
+
final public function setIntoLocal($into_local) {
$this->intoLocal = $into_local;
return $this;
@@ -1360,6 +1370,13 @@
$strategy = $this->selectMergeStrategy();
$this->setStrategy($strategy);
+ $is_pick = $this->getPickArgument();
+ if ($is_pick && !$this->isSquashStrategy()) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'You can not "--pick" changes under the "merge" strategy.'));
+ }
+
// Build the symbol ref here (which validates the format of the symbol),
// but don't load the object until later on when we're sure we actually
// need it, since loading it requires a relatively expensive Conduit call.
@@ -1486,16 +1503,7 @@
continue;
}
- $symbols = null;
- foreach ($set->getCommits() as $commit) {
- $commit_symbols = $commit->getDirectSymbols();
- if ($commit_symbols) {
- $symbols = $commit_symbols;
- break;
- }
- }
-
- if ($symbols) {
+ if ($set->hasDirectSymbols()) {
continue;
}
@@ -1524,6 +1532,18 @@
// set of commits, and try to confirm that the state we're about to land
// is the current state in Differential.
+ $is_pick = $this->getPickArgument();
+ if ($is_pick) {
+ foreach ($sets as $key => $set) {
+ if ($set->hasDirectSymbols()) {
+ $set->setIsPick(true);
+ continue;
+ }
+
+ unset($sets[$key]);
+ }
+ }
+
return $sets;
}
diff --git a/src/workflow/ArcanistLandWorkflow.php b/src/workflow/ArcanistLandWorkflow.php
--- a/src/workflow/ArcanistLandWorkflow.php
+++ b/src/workflow/ArcanistLandWorkflow.php
@@ -32,7 +32,9 @@
etc.
When you provide a __ref__, all unpublished changes which are present in
-ancestors of that __ref__ will be selected for publishing.
+ancestors of that __ref__ will be selected for publishing. (With the
+**--pick** flag, only the unpublished changes you directly reference will be
+selected.)
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
@@ -222,6 +224,11 @@
'complicated changes by allowing you to make progress one '.
'step at a time.'),
)),
+ $this->newWorkflowArgument('pick')
+ ->setHelp(
+ pht(
+ 'Land only the changes directly named by arguments, instead '.
+ 'of all reachable ancestors.')),
$this->newWorkflowArgument('ref')
->setWildcard(true),
);
@@ -308,6 +315,7 @@
$revision = $this->getArgument('revision');
$strategy = $this->getArgument('strategy');
+ $pick = $this->getArgument('pick');
$land_engine
->setViewer($this->getViewer())
@@ -324,6 +332,7 @@
->setIntoEmptyArgument($into_empty)
->setIntoLocalArgument($into_local)
->setIntoArgument($into)
+ ->setPickArgument($pick)
->setIsIncremental($is_incremental)
->setRevisionSymbol($revision);
diff --git a/src/workflow/ArcanistWorkWorkflow.php b/src/workflow/ArcanistWorkWorkflow.php
--- a/src/workflow/ArcanistWorkWorkflow.php
+++ b/src/workflow/ArcanistWorkWorkflow.php
@@ -38,7 +38,7 @@
switch to it. If it does not find one, it will attempt to create a new branch
or bookmark.
-When "arc work" creates a branch or bookmark, it will use "--start" as the
+When "arc work" creates a branch or bookmark, it will use **--start** as the
branchpoint if it is provided. Otherwise, the current working copy state will
serve as the starting point.
EOHELP

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 8, 10:30 PM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7384735
Default Alt Text
D21340.diff (6 KB)

Event Timeline